编译流程包括四个阶段:预处理(预编译),编译,汇编,链接
编译流程的基本图如图:
一.预处理
gcc -E main.c -o main.i
预处理相当于根据预处理指令组装新的c/c++程序。经过预处理,会产生一个没有宏定义,没有条件编译指令,没有特殊符号的输出文件,读取c/c++源程序,对其中的伪指令(以#开头的指令)进行处理,具体为下:
1. 将所有的#define删除,并且展开所有的宏定义(字符替换)
2. 处理所有的条件编译指令。如:#if,#end if, #else等。
3. 处理#include预编译指令,将被包含的文件插入到该预编译指令的位置。
4. 删除所有的注释。
5. 添加行号和文件名标识。
6. 保留所有的# pragma编译器指令
预处理过程实质上是文本处理#,将#include包含的头文件直接拷贝到.C文件中以及删除注释
二.编译
gcc -s main.i -o main.s
将预处理完的文件进行一系列语法分析,语义分析,词法分析,词义分析,代码优化后产生相应的汇编代码文件
三.汇编
gcc -c main.s -o main.o
将编译完的汇编代码文件翻译成机器指令,并生成可重定位目标程序的.o文件,该文件为二进制文件,字节编码是机器指令,根据汇编指令和机器指令的对照表一一翻译
四.链接
gcc -o main main.o
通过链接器将一个个目标文件(或许还有库文件),链接在一起生成一个完整的可执行程序。就像main.c使用到了C标准库的东西printf,但是编译过程只是把源文件翻译成二进制而已,这个二进制还不能直接执行,这个时候就需要做一个动作,将翻译成的二进制与需要用到库绑定在一块。在运行的时候这些”绳子”就将对应的库函数”签过来”