引言
在上一篇的文章中,我们介绍了C/C++这类编译型语言的编译、链接大概流程,本篇我们就针对C/C++编译过程中涉及的几种处理工具进行简单的介绍。包括如下几个:
预处理器、编译器、汇编器、链接器
下面我们主要介绍GCC(GCC Compiler Collection)编译套件中对应的工具
1. 预处理器
-
作用
顾名思义,其作用就是用来对源代码(.cpp)进行预处理的,包括 注释删除、头文件展开、宏替换。 -
文件格式变化
输入 *.cpp ,输出 *.i -
GCC中对应工具或命令
g++ -E test.cpp -o test.i
上面的 -E 选项就是告诉编译器,只执行预处理操作,不往下执行其他编译操作。
通常我们在编译的时候不会单独执行这个操作,一般编译的命令里面会自动执行预处理。我们这里主要是以学习为目的。当然在某些场景下,上面这个命令也会有作用,比如当我们增加了一些宏定义的逻辑,想看看有没有生效,我们可以通过上面的命令来生成 .i 文件,然后打开看看对应宏的值是什么即可。
2. 编译器
-
作用
编译阶段主要是对预处理后的文件进行 词法分析、语法分析、语义分析 ,从而判断代码是否符合规范,我们常见的编译错误,大多就是该阶段检测出来的。 -
文件格式变化
输入 *.i,输出 *.s -
GCC中对应工具或命令
g++ -S test.i -o test.s
输出的.s就是汇编语言文件。内容都是汇编指令。
3. 汇编器
-
作用
汇编阶段主要是对 .s 汇编文件进行汇编处理,将符号指令翻译成二进制指令目标文件。 -
文件格式变化
输入 *.s,输出 *.o -
GCC中对应工具或命令
g++ -c test.s -o test.o
输出的.o是可重定位的目标文件,用于下一阶段的链接。
4. 链接器
-
作用
一个目标文件中通常会调用一些其他目标文件(.o 、.so、.a)中的指令。链接器就像一个粘合剂,负责将这些存在依赖关系的目标文件链接到一起,最终生成一个更大的二进制目标文件,比如可执行文件或者库文件。 -
文件格式变化
输入 .o,输出 可执行文件 或者 .a 、.so库文件。 -
GCC中对应工具或命令
g++ test.o -o test // 无库依赖,直接生成可执行文件
ar cqs targetstaticlib.a test.o other.o // 生成静态链接库
g++ -fPIC -shared -o targetdynamiclib.so test.o other.o // 生成动态链接库
g++ test.o -o test -L. -lsoname // 引用其他库文件,生成可执行文件
背后使用的是ld类似的链接工具。
注意 以上阶段中,不需要一个个执行,g++编译工具会根据输入的文件格式和参数,来自动执行对应的流程。例如 g++ test.cpp -o main 会执行预处理、编译、汇编所有流程。
以上就是对预处理、编译、汇编、链接流程的简单介绍。对于GCC之类的编译套件 以及 动态库、静态库,我们后面也会单独再介绍。从下一篇开始,我们正式进入C++编程知识的学习。