一、编译流程
.c源文件 => 预处理 => 编译 => 汇编 => 链接 => 可执行文件
1. 预处理 gcc -E
cpp
# 预处理main.c,得到预处理后的文件main.i
# .i为预处理文件的统一后缀
gcc -E main.c -o main.i
有以下目的:
- 调试宏定义是否展开
- 查看引入.h文件后的完整代码
- 排查条件编译引入的问题
2. 编译 gcc -S
cpp
# 编译main.c,生成编译后的汇编文件main.s
# .s为汇编文件的后缀
gcc -S main.c -o main.s
这一步主要用来分析汇编代码
3. 汇编(生成目标文件但不进行链接) gcc -c
cpp
# 汇编main.c,输出目标文件main.o
gcc -c main.c -o main.o
将各.c文件编译为.o文件,各个.o文件链接后生成可执行文件
4. 链接
链接的操作就是将各个.o文件内相互引用的函数、变量等链接起来,找到各自的符号,然后再输出一个可执行文件。
二、objdump工具
- 反汇编二进制文件(代码段)
- 查看源码的section信息
- 查看符号表查看头文件
三、静态链接与动态链接
- 静态链接
GCC会尝试将所有用到的库函数直接链接到最终生成的可执行文件中
- 动态链接
库只有在被调用时才被加载进文件中,而不是全部加载到文件中进行编译。所以动态链接的可执行文件比静态链接的小。

main为静态链接,main1为动态链接,二者.c文件相同,但不同的链接方式造成编译后文件出现较大的体积差异,主要是因为静态链接将stdio内的函数链接到了可执行文件中。