C语言通过编译器【gcc】生成可执行文件,这其中是直接就生成了可执行文件吗?
gcc test.c -o test
其实并不是,C语言的编译存在四个步骤。
test.c-------(1)------->test.i--------(2)------>test.s------(3)------>test.o------(4)------>test
(1)是预处理过程。
预处理用于将所有的#include头文件以及宏定义替换成其真正的内容,
预处理之后得到的仍然是文本文件,但文件体积会大很多。gcc的预处理是预处理器cpp来完成的,你可以通过如下命令对test.c进行预处理:
gcc -E -I./inc test.c -o test.i
或者直接调用cpp命令
$ cpp test.c -I./inc -o test.i
上述命令中-E是让编译器在预处理之后就退出,不进行后续编译过程;-I指定头文件目录,这里指定的是我们自定义的头文件目录;-o指定输出文件名。
(2)是编译过程。
这里的编译不是指程序从源文件到二进制程序的全部过程,而是指将经过预处理之后的程序转换成特定汇编代码(assembly code)的过程。
(3)是汇编过程。
汇编过程将上一步的汇编代码转换成机器码(machine code),这一步产生的文件叫做目标文件,是二进制格式。gcc汇编过程通过as命令完成:
$ as test.s -o test.o
等价于:
gcc -c test.s -o test.o
这一步会为每一个源文件产生一个目标文件。因此mymath.c也需要产生一个mymath.o文件。
(4)是链接过程。
链接过程是将多个目标文件【.o文件】以及所需要的外部库。