C++编译链接全流程解析
·
整个过程可以分为:预处理 (Preprocessing)、编译 (Compilation)、汇编 (Assembly) 和 链接 (Linking)。
1. 预处理 (Preprocessing)
执行工具:cpp
核心任务:处理所有以 # 开头的指令。
-
宏替换:将所有
#define定义的宏进行文本替换。 -
头文件包含:将
#include指定的文件内容完整插入到当前位置。 -
条件编译:根据
#if、#ifdef等指令过滤掉不符合条件的代码块。 -
去注释:删除所有的代码注释。
-
生成文件:
.i文件(依然是可读的源代码,但体积巨大)。
2. 编译 (Compilation)
执行工具:cc1 / cc1plus
核心任务:将预处理后的源代码转换为针对特定架构的汇编代码。
-
词法/语法分析:检查代码是否符合 C++ 语法规则 。
-
语义分析:检查变量类型是否匹配等逻辑错误。
-
优化:进行代码优化(如常量折叠、死代码消除)。
-
生成文件:
.s文件(汇编语言代码)。
3. 汇编 (Assembly)
执行工具:as
核心任务:将汇编指令翻译成机器码(二进制)。
-
指令映射:将汇编指令逐条对应到 CPU 的机器指令。
-
生成文件:
.o或.obj文件(目标文件)。注意:此时的文件已经是二进制格式,但由于函数调用地址尚未确定,它还不能直接运行。
链接 (Linking)
这是你简历中提到“静态库/共享库” 的关键步骤。 执行工具:ld
核心任务:符号解析与重定位
-
符号解析 (Symbol Resolution):将每个符号引用(如函数调用
foo())与符号定义关联起来。如果在其他文件找不到定义,就会报著名的undefined reference错误。 -
重定位 (Relocation):由于编译阶段各文件的地址都是从 0 开始的虚拟地址,链接器会将多个目标文件合并,为函数和变量分配最终的运行时内存地址。
静态链接 vs. 动态链接
| 特性 | 静态链接 (.a / .lib) | 动态链接 (.so / .dll) |
| 链接时间 | 编译时完成 | 程序运行时加载 |
| 执行文件大小 | 较大(库代码打包进程序) | 较小(仅包含库的引用) |
| 内存占用 | 多个程序运行会有多份库副本 | 多个程序共享物理内存中的一份库 |
| 更新便捷性 | 差(需重新编译整个程序) | 好(只需替换 .so 文件) |
更多推荐


所有评论(0)