# 编译 vs 链接
# 一、编译
编译又包含了:预处理
、编译
、汇编
和链接(二进制可重定位文件)
。
graph LR
A(hello.c) -- -E_预处理 -->B(hello.i)
B -- -S_编译 --> C[hello.s]
C -- -c_汇编 --> E[hello.o]
E -- 链接 --> F(可执行文件)
1
2
3
4
5
2
3
4
5
# 1. 预处理:
gcc -E hello.c -o hello.i
1
- 将所有的“#define”删除,并且展开所有的宏定义
- 处理所有的条件编译指令,比如
#if
、#ifdef
、#elif
、#else
、#endif
- 处理
#include
预编译指令,将被包含的头文件插入到该编译指令的位置。(这个过程是递归进行的,因为被包含的文件可能还包含了其他文件) - 删除所有的注释
//
和/* */
。 - 添加行号和文件名标识,方便后边编译时编译器产生调试用的行号心意以及编译时产生编译错误或警告时能够显示行号。
- 保留所有的
#pragma
编译指令,因为编译器需要使用它们
# 2. 编译:
gcc -S hello.i -o hello.o
1
- 编译过程是整个程序构建的核心部分,编译成功,会将源代码由文本形式转换成机器语言,编译过程就是把预处理完的文件进行一系列词法分析、语法分析、语义分析以及优化后生成相应的汇编代码文件。
# 3. 链接:
gcc hello.o -o hello
1