GCC编译器
gcc可以用于编译C代码(g用于编译C代码)
编译过程
原始的 test.cpp 文件
-
预处理:生成
.i文件在这一步骤中,编译器会对宏定义、常量进行处理,比如对常量进行替换操作。
1
2# -E 表示仅进行预处理。
g++ -E test.cpp -o test.i
CONST_NUM被替换成了40,同时前面的iostream库也被导入近来,所以会突增到28650行。 -
编译:生成
.s文件将代码转化为汇编语言。
1
2# -S 表示仅进行汇编
g++ -S test.i -o test.s
汇编程序。
-
汇编:生成
.o文件将汇编代码转化为计算机能理解的二进制代码。
1
2# -C 表示仅进行汇编
g++ -c test.s -o test.o
二进制代码。
-
链接:生成可执行的二进制程序。
将系统中的库链接到当前程序中。
1
2# -o 将可执行文件命名为指定的名字
g++ test.o -o test
在实际使用过程中,可以直接使用下面的这一步。其隐式的包含了前面四步。
1 | g++ test.cpp -o test |
g++编译参数
-
-g编译带调试信息的可执行文件。这意味着代码可以被GDB调试1
g++ -g test.cpp -o test
-
-O[n]优化源代码。编译器会对代码进行优化,比如去除没用过的变量。提高可执行文件的运行速度。一般情况下
-O2就已经足够了。-O与-O1都是初步优化。 -
-l和-L都用于指定链接库。-l为库名。-L为库的位置。默认情况下,程序都是在
/lib,/usr/lib和/usr/local/lib中寻找库,此时无需参数-L。1
g++ -lOfiicialLib test.cpp # 链接的库为OfficialLib
但如果是自己写的库,需要指定位置,那么就需要使用
-L。1
g++ -L/home/abc/MyLibFolder -lMyLib test.cpp
-
-I指定头文件位置。1
g++ test.cpp -Iinclude # include下保存了test.cpp中需要的.h文件
g++多文件编译
文件结构如图所示。
-
最简单直接的方式
1 | # 最简单的方式 |
-
生成库后再运行
-
静态库版本:将
src.cpp生成一个静态库,随后再链接到main.cpp上。1
2
3
4
5
6
7
8
9
10
11
12
13cd src # 在src文件夹下
#在./src/下
#开始生成静态库
g++ swap.cpp -c -I../include # -c表示生成一个二进制文件 -I制定了swap.h中头文件所在位置
# 随后,会输出一个swap.o的二进制文件
ar rs libSwap.a swap.o # 将二进制文件归档为静态库文件libSwap.a
# 随后,会输出一个lisSwap.a
# 此时 src内保存了:libSwap.a swap.cpp swap.o
cd .. # 回到核心目录下
# 此处在./文件夹下
# 链接静态库
g++ main.cpp -Iinclude -Lsrc -lSwap -o static_main.out # 注意,这里的-l后面写的是Swap是因为,-l操作会自动的在后接上的内容(Swap)前加lib后加.a。此时-l会去寻找libSwap.a
-
动态库版本:
1
2
3
4
5
6
7
8cd src
#在./src下进行
g++ swap.cpp -I../include -fPIC -shared -o libSwap.so # -fPIC 表示生成与位置无关文件,动态链接库必备。 -shared表示生成动态链接库
cd ../
#在./下进行
#链接动态库
g++ main.cpp -Iinclude -Lsrc -lSwap -o share_main.out # 同理-l会加上东西,但是编译器会优先尝试动态库(libSwap.so)
-
GDB调试器
在Vscode中调试代码
点击图片中的”创建launch.json文件"
launch.json文件的编写如下
1 | // launch.json |
注意修改program选项,指定为my_cmake_exe。同时,在根目录的CMakeLists.txt中应该编写set(CMAKE_BUILD_TYPE Debug),并且确保set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")中没有设置-O2选项,避免因为优化代码,导致调试的不准确。
随后配置tasks.json文件。
点击“配置默认生成任务”,生成一个tasks.json
1 | // tasks.json |
随后,无需再手动编译,直接执行调试就可以对程序自动的进行编译。
再次展示文件结构。
CMake
跨平台的安装编译工具,可以用于描述所有平台的编译过程。没有Cmake,你就需要给每一个平台都写一个工程构建文件(比如Makefile、Xcode等)。有了Cmake,你只需要与Cmake打交道就可以了,只需要修改CMakeList.txt。
基本语法
1 | 指令(参数1 参数2 参数3) |
-
参数之间需要用空格或分号分开,逗号用不了。
-
指定与大小写无关,参数和变量是大小写相关的。
-
${}用于变量取值。在IF语句中可以直接使用变量名。
常用指令
1 | cmake_minimum_required(VERSION 2.8.3) # 设置CMake最小版本号为2.8.3 |
常用变量
1 | CMAKE_C_FLAGS # gcc编译选项 |
编译流程
-
编写一个CMakeList.txt。
-
执行
cmake PATH生成Makefile(linux下)。 PATH是顶层CMakeList.txt所在的目录,比如在主目录中直接编译写好的CMakeList.txt,就可以写
cmake .。 -
执行
make进行编译。
在编译过程中,有两种构建方式。第一种是内部构建,其意思是指直接在工程主目录下进行cmake指令,直接就是cmake .+make。第二种是外部编译,其含义为现创建一个build目录,进入到build目录后,在目录内部执行cmake ..的命令来编译位于上级目录中的CMakeList.txt,随后的make指令也在build目录中执行。