#################
# 2、编译和链接
#################
编译过程分解为4个步骤:预编译、编译、汇编和链接。
// hello.c
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
(1)预编译 [gcc -E]
源代码文件(hello.c)和相关的头文件(stdio.h)被预编译器cpp预编译成一个.i文件(C++预编译后的文件扩展名是.ii)。
[xiaoloaw@AONT03 partTwo]$ gcc -E hello.c -o hello.i // -E 只运行 C 预编译器
// or
[xiaoloaw@AONT03 partTwo]$ cpp hello.c > hello_cpp.i
预编译过程主要处理那些源代码文件中的以"#"开始的预编译指令:
- 将所有的"#define"删除,并且展开所有的宏定义;
- 处理所有条件预编译指令,比如"#if"、"#ifdef" ... ;
- 处理"#include"预编译指令,将被包含的文件插入到该预编译指令的位置,这个过程是递归进行的;
- 删除所有的注释 // 和 /* */;
- 添加行号和文件名标识,以便编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号;
- 保留所有的#pragma编译器指令,因为编译器需要使用它们;
(2)编译 [gcc -S]
编译过程就是把预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后产生相应的汇编代码文件。
[xiaoloaw@AONT03 partTwo]$ gcc -S hello.i -o hello.s // -S 产生汇编源文件
(3)汇编 [as / gcc -c]
汇编器(as)将汇编代码转变成机器可以执行的指令。
[xiaoloaw@AONT03 partTwo]$ as hello.s -o hello.o // as 是汇编器
// or
[xiaoloaw@AONT03 partTwo]$ gcc -c hello.s -o hello.o // -c 只编译并生成目标文件
(4)链接 [ld] 目标文件和库一起链接形成最终可执行文件
[xiaoloaw@AONT03 partTwo]$ ld -static /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc/i686-redhat-linux/4.4.4/crtbeginT.o -L/usr/lib/gcc/i686-redhat-linux/4.4.4/
-L/usr/lib -L/lib/ hello.o --start-group -lgcc -lgcc_eh -lc --end-group /usr/lib/gcc/i686-redhat-linux/4.4.4/crtend.o /usr/lib/crtn.o
省略所有路径,如下
ld -static crt1.o crti.o crtbeginT.o hello.o --start-group -lgcc -lgcc_eh -lc --end-group crtend.o crtn.o