c++:编译链接过程
目录
🧰 总览:C++程序从源码到执行的完整过程
🔧 一、预处理(Preprocessing):处理 #include 和宏定义
🧠 二、编译(Compilation):把 C++ 转成汇编语言
🛠️ 三、汇编(Assembly):将汇编代码转为机器码(二进制)
🔗 四、链接(Linking):把所有目标文件拼接成可执行程序
涉及两种链接:
⚙️ 五、举个实际例子:Linux下用g++编译
🧩 六、图解:C++ 构建流程
🧰 总览:C++程序从源码到执行的完整过程
C++ 程序构建过程通常分为 4 个主要阶段:
源代码(.cpp)↓ [预处理器 Preprocessor]
预处理后的代码↓ [编译器 Compiler]
汇编代码(.s 或 .asm)↓ [汇编器 Assembler]
目标文件(.o 或 .obj)↓ [链接器 Linker]
可执行文件(.exe 或 ELF)
🔧 一、预处理(Preprocessing):处理 #include
和宏定义
工具:预处理器
-
把
#include
文件展开为真实代码 -
把
#define
宏替换为实际值 -
去掉注释
示例:
#include <iostream>
#define PI 3.14
int main() {std::cout << PI << std::endl;
}
经过预处理后可能变成:
// 展开iostream
std::cout << 3.14 << std::endl;
✅ 输出文件:预处理后的 .i
文件(可选)
i
代表 intermediate
(中间文件)或 preprocessed input
(预处理输入)
🧠 二、编译(Compilation):把 C++ 转成汇编语言
工具:编译器(如 g++
, clang
, MSVC
)
-
将预处理后的 C++ 代码 ➜ 翻译成汇编代码
-
检查语法错误、类型检查
-
做一些优化(内联函数、常量传播等)
示例:
int add(int a, int b) { return a + b; }
编译后变成汇编语言 .s
文件(含 CPU 指令)
✅ 输出文件:汇编文件(.s
)
s 代表 source,特指汇编源代码(Assembly code)
🛠️ 三、汇编(Assembly):将汇编代码转为机器码(二进制)
工具:汇编器(Assembler)
-
将
.s
汇编代码 ➜ 转成机器可读的二进制.o
(Linux)或.obj
(Windows)文件 -
这就是所谓的目标文件(Object File)
✅ 输出文件:目标文件(.o
或 .obj
)
o 的意思:object,目标文件(Object File)
🔗 四、链接(Linking):把所有目标文件拼接成可执行程序
工具:链接器(Linker)
-
把多个
.o
文件组合在一起(可能还有库) -
解析函数调用(谁调用谁?在内存中地址是多少?)
-
加入外部库函数(如
std::cout
的定义) -
生成最终的
.exe
或.out
文件
涉及两种链接:
类型 | 描述 |
---|---|
静态链接 | .lib / .a 文件代码复制到程序中 |
动态链接 | 程序运行时加载 .dll / .so 文件 |
✅ 输出文件:最终可执行文件(.exe
, .out
, a.out
)
exe 的意思:executable,可执行文件(Executable)
⚙️ 五、举个实际例子:Linux下用g++编译
g++ main.cpp -o myprog
你其实执行的是整个流程:
-
预处理器:展开头文件
-
编译器:转汇编
-
汇编器:生成
.o
-
链接器:生成可执行文件
myprog
你可以分阶段运行:
g++ -E main.cpp -o main.i # 仅预处理
g++ -S main.cpp -o main.s # 编译成汇编
g++ -c main.cpp -o main.o # 编译+汇编(不链接)
g++ main.o -o myprog # 链接
🧩 六、图解:C++ 构建流程
[C++ 源代码 .cpp]↓ 预处理器(g++ -E)
[展开宏后的代码 .i]↓ 编译器(g++ -S)
[汇编语言 .s]↓ 汇编器(g++ -c)
[目标文件 .o / .obj]↓ 链接器(g++)
[最终可执行程序 .exe / a.out]