gcc编译

gcc的下载(下载mingw,里面包含gcc)
下载安装MinGW-w64详细步骤(c/c++的编译器gcc的windows版,win10真实可用)

gcc编译可执行文件

由源码转换为可执行文件要顺序经过四个步骤
1、预处理(pre processing)
2、编译(compiling)
3、汇编(assembling)
4、链接(linking)

预处理gcc命令:

预处理
gcc -E main.c -o main.i
其中 -E -o 是编译选项,-E 指预处理,-o 指生成的目标文件。生成的为 .i 文件(扩展文件)。

编译gcc命令:

编译
gcc -S main.i -o main.s
其中 -S 指编译。生成的为 .s 文件。

汇编gcc命令:

汇编
gcc -c main.s -o main.o
其中 -c 指汇编。生成的为 .o 文件(目标文件)。

链接gcc命令:

链接
gcc main.o -o main
生成的为可执行文件(windows下为.exe)。

gcc main.c -o main
上述命令由源文件生成可执行文件,过程中依然是先构建目标文件,只不过目标文件在编译可执行文件后删除。

gcc的编译过程中,不同阶段执行的动作不同。

预处理阶段:

这个步骤的动作会把源文件中引入的头文件展开和一些宏定义的替换。

编译阶段:

这个步骤的动作会先检查源码中是否有语法错误等,然后将高级语言转换为汇编语言。

汇编阶段:

这个步骤的动作会根据编译生成的汇编语言文件,生成二进制代码的目标文件。

链接阶段:

这个步骤是对目标文件中只有声明但没有实现的方法做一个链接库的动作。库包含静态库和动态库,库里包含了方法的实现。

参考
GCC编译的四个阶段
gcc编译的四个过程

静态库和动态库

其中,当一个项目需要引用到别的项目的方法或内容,项目很难将对方的源码引入,这时可以将对方的源码编译成一个库,在编译己方项目时,通过链接库的方法来获取其他项目函数的实现。静态库和动态库的区别为,静态库会编译进可执行文件中。而动态库不随可执行文件,由可执行文件执行到需要动态库的时候才去动态库里找实现。在linux系统中,静态库为.a文件,动态库为.so文件;在windows系统中,静态库为.lib文件,动态库为.dll文件。

gcc编译静态库的方法

ar -rc libtest.a .\test.o

首先由test.c编译出目标文件test.o,根据目标文件生成静态库libtest.a。

gcc编译链接静态库的方法

gcc -o main.exe main.o -L .\test1\ -l test

其中使用 -o 指定目标生成main.exe,是根据main.o生成的。-L 指要链接的文件夹./test/,是所需头文件的路径,-l 指定要链接的库libtest.a,test为库名。

gcc编译动态库的方法

gcc -fPIC -shared test.o -o libtest.so
gcc -fPIC -shared test.c -o libtest.so

在windows系统下动态库的文件格式为dll
gcc -fPIC -shared test.o -o libtest.dll

其中 -shared 说明要编译的是共享库(动态库),动态库可由源文件或目标文件编译而成。

gcc编译使用动态库的方法

如果直接在gcc命令上链接使用动态库会产生报错,找不到动态库。是因为系统默认寻找的动态库路径不包含本项目生成的动态库所在路径,有以下处理:

linux环境下要成功链接动态库有两种方法:
1、将动态库的路径加入到环境变量中

export LD_LIBRARY_PATH=/yourpath:$LD_LIBRARY_PATH

其中 /yourpath 需要修改为动态库所在的绝对路径

2、将动态库复制到 /usr/lib 或 /lib 目录下,这两个是系统默认找动态库的路径

cp libtest.so /usr/lib

windows环境下(目前尝试了一种方法可行):

1、将动态库复制到可执行文件的同一目录下

gcc编译的链接语句和静态库一样

gcc -o main.exe main.o -L . -l test

其中-L . 的 . 指定在当前目录下找

参考帖子:
【gcc】 gcc编译动态库(共享库)、静态库|链接静态库、动态库
GCC编译过程与动态链接库和静态链接库,很详细

cmake编译

cmake和make下载
Windows下CMake的下载与安装详解
windows下安装make

为什么有makefile,cmake,cmakelists

gcc在编译单个文件或少量文件的时候很适用,但随着项目的发展,一个项目往往有大量的文件,此时再一个个敲gcc会稍显麻烦。为了解决文件数过多使用gcc难编译的问题,makefile根据其中的编译规则使用一行shell命令make即可完成大量文件的编译,极大的提高了编译效率。
参考
CMake与CMakeLists是干什么的?

而cmake和cmakelists则是生成makefile的工具和文件。

cmake编译由源文件生成可执行文件的流程分两个阶段:
1、cmake根据cmakelists生成makefile
2、在makefile目录下执行make命令生成可执行文件

编写cmakelists

下面是编写cmakelists的一些简单规则:

main模块

cmake_minimum_required(VERSION 3.24)   # 设置cmake的最小版本MESSAGE("start")   # MESSAGE可在执行cmakelists的过程中在控制台打印信息project(c_test01 C)   # 编译的项目名MESSAGE("middle")
#set(CMAKE_C_STANDARD 11)add_subdirectory(test1)   # 把子文件夹也要编译#include_directories(test1)   # 将该文件夹的头文件引入
#link_libraries(test1)   # 链接静态库用,需要在add_executable前使用add_executable(c_test01 main.c)   # 生成可执行文件TARGET_LINK_LIBRARIES(${PROJECT_NAME} test1)   # 链接动态库用,在add_executable后使用MESSAGE("end")

test模块

#add_library(test1 STATIC test.c)   # 生成静态库add_library(test1 SHARED test.c)   # 生成动态库

其中:
设置cmake版本

cmake_minimum_required(VERSION 3.24)

这里设置编译本项目的cmake最低版本为3.24,一般在cmakelists的开头。可以通过 cmake --version 查看当前的cmake版本,如果当前版本小于上述要求的最低版本,则编译停止。

设置项目名

project(c_test01 C)

声明项目的名字c_test01,后面的 C 是可选项,说明该项目是C语言的

添加子文件夹

add_subdirectory(test1)

编译本项目时将子文件也进行编译,子文件需要包含cmakelists

生成可执行文件

add_executable(c_test01 main.c)

生成可执行文件c_test01,源码为main.c。这里相当于gcc main.c -o mian.exe。

将子文件夹的头文件引入

include_directories(test1)

将该文件夹下的头文件引入到本项目

生成静态库和动态库

add_library(test1 STATIC test.c)
add_library(test1 SHARED test.c)

这两个是在子文件夹下生成静态库和动态库的,test1位库名。STATIC和SHARED指定库为静态库和动态库。库的源码是test.c。

链接静态库

link_libraries(test1)

这个是链接静态库的语句,由于静态库会编译进可执行文件中,所以要在add_executable前使用。

链接动态库

TARGET_LINK_LIBRARIES(${PROJECT_NAME} test1)

这个是链接动态库的语句,由于动态库是在可执行文件执行的过程中才使用,所以在add_executable后使用。

执行cmakelists过程中打印信息

MESSAGE(“start”)
MESSAGE(“middle”)
MESSAGE(“end”)

message是cmakelists的语言规则中可以打印信息到控制台的方法,message可以加一些选项规定打印信息的等级。参考
CMake的内置变量与message打印的用法

cmakelists的语法参考
CMakeLists详解
CMakeLists 入门

使用cmakelists方法

在要编译的cmakelists目录下新建一个build文件夹,这是一种约定俗成的使用习惯。因为执行cmakelists会生成很多文件,为了不影响项目的观感,故将这些文件放在build文件夹下。

mkdir build

然后进入build文件夹执行cmakelists

cd build
cmake ..
# 因为进入到主项目的build的文件夹,而cmakelists在build文件夹的退一层,所以需要 cmake ..
# 如果这步报错可以看看是不是本帖后面遇到的问题

此时build文件夹下会生成makefile和其他文件

然后就可以在build的目录下执行makefile来生成可执行文件和库文件了

make
# 如果有报错也可以看看是不是本帖后面遇到的问题


接下来就可以执行可执行文件了,由于这里是在windows环境下,链接动态库需要将动态库复制到可执行文件同一目录下

cp .\test1\libtest1.dll ./


执行可执行文件

.\c_test01.exe

初次使用遇到问题

其中,在windows使用cmakelists编译过程中

执行

cmake ..

遇到一个小问题

CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage

这里是cmake编译器没指定,解决方法为

cmake -G "MinGW Makefiles" ..

参考
CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage

接着遇到问题

CMake Error: CMake was unable to find a build program corresponding to “MinGW Makefiles”. CMAKE_MAKE_PROGRAM is not set. You probably need to select a different build tool. CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage

出现这种问题一般是在安装MinGW 时没有下载相应的 make 的文件,解决办法为

打开MinGW Installation Manager,选择make文件下载

参考
CMake Error: CMake was unable to find a build program corresponding to “MinGW Makefiles“ 解决办法

接着在执行make命令的时候,遇到问题

make : 无法将“make”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 所在位置 行:1 字符: 1

在安装mingw的时候已经安装了make的exe,但名字为mingw32-make.exe,所以要么改一下make文件的名字,或者直接使用mingw32-make。

mingw32-make

参考
VSCODE中使用CMAKE遇到的问题及其解决方法
windows下安装make

在执行可执行文件的过程中,遇到问题

由于找不到dll,无法继续执行代码,重新安装程序

这个是找不到动态库,我的做法是直接把动态库复制到当前可执行文件所在的目录。

cp .\test1\libtest1.dll ./

windows默认查找动态库的方法有几种,

1.exe文件所在的目录下;
2.进程当前的工作目录;
3.Windows系统目录;
4.Windows目录;
5.环境变量Path下的一系列目录;

参考
VS环境下,关于“找不到 **.dll,无法执行代码,重新安装程序可能会解决此问题。”的四种解决方案

gcc编译可执行文件和cmake编译可执行文件相关推荐

  1. linux cmake 编译64位,cmake编译win下64位obs

    obs是一款开源编码推流工具,简单易用,非常流行. 一次项目中,发现本台式机I3处理器下32位obs推流CPU使用率100%.而使用的第三方设备在64位下,性能较好. 所以需要编译64位obs并且编译 ...

  2. c语言编译 64位,cmake – 编译32位和64位

    正如我在评论中所说,这是我们如何做到这一点的一个例子. if( CMAKE_SIZEOF_VOID_P EQUAL 8 ) MESSAGE( "64 bits compiler detect ...

  3. 乐鑫esp8266学习rtos3.0笔记:如何在 windows 用 CMake 编译 ESP8266 项目。

    本系列博客学习由非官方人员 半颗心脏 潜心所力所写,不做开发板.仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 基于C SDK的ESP8266开发技术全系列笔记 一.N ...

  4. 使用CMake编译OsgEarth

    编译OsgEarth之前需要编译依赖的Lib: 1.编译OSG VS2015+QT5.10+x64编译OSG 2.编译Geos 使用CMake编译Geos3.5.0 3.编译GDAL 使用nmake编 ...

  5. ubuntu系统上,对.cu文件进行编译,生成.so或可执行文件

    本文主要介绍在ubuntu系统上,怎样对.cu文件进行编译,生成.so或可执行文件. 一.cuda文件 后缀为.cu的文件,里面主要利用cuda进行高效的并行计算. 二.编译 主要有2种编译方法: 1 ...

  6. CMake编译工具与项目构建

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 文章导读 本文从C/C++代码的编译过程入手,弄清楚Make与Ma ...

  7. 一文详解CMake编译工具与项目构建

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 文章导读 本文从C/C++代码的编译过程入手,弄清楚Make与Makefile,CMake与CMake ...

  8. 如何使用CMake编译RTT微内核

    已经大半个月没有更新文章了,大家还记得之前作者写的一篇关于RT-Thread的微内核移植的文章吗?如果不记得没关系.看如下是文章链接. <如何移植RTT微内核到树莓派3B> 目前RTT微内 ...

  9. Geant4采用make和cmake编译运行geant4自带例子的方法

    该教程介绍如何将geant4中自带的例子通过camke编译成可执行文件,并运行程序. 1 在linux主目录下创建一个geant4_workdir目录,并将geant4自带的例子B1复制到该目录下,如 ...

最新文章

  1. [links]一写国内外著名人物的blog链接
  2. 关于ML.NET v0.7的发布说明
  3. Restful API 中的错误处理方案
  4. 源码免杀处理的技巧与tips
  5. 有计算机信号专业吗,计算机医学图像及信号处理
  6. linux wifi 配置 编程,linux 无线手动配置
  7. oracle连续周数,详细讲解Oracle数据库的“周数计算”
  8. linux系统用w程序,Linux w命令
  9. ceres-solver库编译说明
  10. ibm刀片机服务器安装系统,IBM刀片服务器安装.doc
  11. 大屏制作 | 完成一个美观大屏到底多简单?四步完成
  12. springmvc中使用forward和redirect
  13. sd和sem啥区别_生物统计学-标准差(SD)和标准误(SEM)有何区别.pdf
  14. Python实现邮箱自动群发工资条
  15. Spark日志,及设置日志输出级别
  16. 模仿微信头像 单人 以及群聊的 头像
  17. CUMCM-2017-problem-A
  18. 笔记本计算机名称PC2019,2019值得推荐的13寸笔记本电脑汇总
  19. Java基础01 Java的安装和配置
  20. 三种基本放大电路的区别、比较

热门文章

  1. 功能全面的格式转换软件-格式工厂提供下载
  2. pojo与java bean_POJO与Java Bean
  3. 报错:Cannot determine value type from string ‘xxxxxx‘
  4. 戴尔发布 P3223DE、P2723DE、P2423DE 显示器:2K 分辨率,搭载 90W 全功能 USB-C
  5. dreamweaver 服务器文件夹 本地站点文件夹,使用站点定义向导定义本地文件夹
  6. 场景化应用全面铺开 2017成为人工智能商业化元年
  7. js php 实现日历签到_php+mysql+jquery实现日历签到功能的过程与步骤
  8. 安装VMware出现无效驱动器 解决方法
  9. 游戏自动按键脚本1:田径四项
  10. c语言程序报告学分信息管理,C语言程序报告学生学籍信息管理系统(总21页