总述
预处理->编译->汇编->链接->加载
步骤 | 输入文件 | 输出文件 | 常见后缀 |
---|---|---|---|
预处理 |
.cpp , .h
|
.i , .ii
|
.i , .ii
|
编译 |
.i , .ii , .cpp
|
.s , .asm
|
.s , .asm
|
汇编 |
.s , .asm
|
.o , .obj
|
.o , .obj
|
链接 |
.o , .obj , .a , .so
|
可执行文件或库文件 |
.exe , .so , .dll , .a , .lib
|
在 C++ 中,编译、链接等步骤的执行顺序通常如下:
1. 预处理 (Preprocessing)
- 在编译阶段开始之前,预处理器对源代码进行处理。
- 主要任务包括:
- 处理预处理指令(如
#include
、#define
、#if
等)。 - 宏展开。
- 文件包含(将头文件的内容插入到源文件中)。
- 处理预处理指令(如
- 预处理后,生成一个处理过的文件,通常称为 "翻译单元"(Translation Unit)。
2. 编译 (Compilation)
- 编译器将预处理后的源代码文件翻译为汇编语言代码。
- 编译器根据 C++ 语法、语义进行语法分析、词法分析、类型检查等工作。
- 编译过程生成目标文件(Object File),通常具有
.o
或.obj
后缀。 - 目标文件包含了机器代码,但还未完成所有链接过程。
3. 汇编 (Assembly)
- 编译器将编译生成的汇编代码(由源代码生成)转化为机器代码。
- 汇编代码会被转换为目标文件。
4. 链接 (Linking)
- 链接器将一个或多个目标文件(
.o
或.obj
)和库文件(如静态库.a
或动态库.so
)合并,生成最终的可执行文件或共享库。 - 链接器负责:
- 解决符号引用(比如函数调用和变量引用)。
- 如果是静态链接,直接将目标文件的内容合并;如果是动态链接,则将外部库的引用与程序代码连接。
- 如果链接器发现缺少符号(例如,某个函数或变量没有定义),会生成链接错误。
- 链接结果是生成最终的可执行文件(如
.exe
或无后缀的可执行文件)。
5. 加载 (Loading)
- 当程序启动时,操作系统的加载器将可执行文件加载到内存中。
- 加载器将程序的代码和数据映射到进程的地址空间中。
- 动态链接的库在程序运行时被加载,并且程序的符号引用会绑定到相应的库函数。
总结执行顺序:
- 预处理:处理宏、文件包含等。
- 编译:将源代码翻译为汇编语言代码,并生成目标文件。
- 汇编:将汇编代码转化为机器码,生成目标文件。
- 链接:将目标文件和库合并,生成可执行文件。
- 加载:操作系统加载可执行文件到内存中运行。
在这一过程中,源代码文件通常先被编译为目标文件,然后通过链接器将多个目标文件、库文件组合成一个完整的程序。
后缀文件
在 C++ 的编译和链接过程中,不同的步骤会生成以下后缀的文件:
1. 预处理 (Preprocessing)
-
输入文件:源代码文件(通常是
.cpp
、.c
或.h
)。 -
生成文件:预处理输出文件。
- 后缀通常是
.i
或.ii
。 - 这是预处理器将
#include
展开、宏替换后的纯 C++ 源代码。 - 可选:这个文件不是编译的必要中间产物,通常只用于调试预处理过程。
- 后缀通常是
2. 编译 (Compilation)
-
输入文件:预处理后的文件(
.i
或.ii
,或直接从.cpp
开始)。 -
生成文件:汇编代码文件。
- 后缀通常是
.s
或.asm
。 - 可选:这个文件是目标代码生成之前的中间产物,默认情况下不会显式保留。
- 后缀通常是
3. 汇编 (Assembly)
-
输入文件:汇编代码文件(
.s
或.asm
)。 -
生成文件:目标文件(Object File)。
- 后缀通常是
.o
(在 Linux 或 Unix 系统)或.obj
(在 Windows 系统)。 - 描述:目标文件是机器码文件,尚未完成符号解析,因此不能直接执行。
- 后缀通常是
4. 链接 (Linking)
-
输入文件:一个或多个目标文件(
.o
或.obj
)以及库文件(静态库.a
或.lib
,动态库.so
或.dll
)。 -
生成文件:可执行文件或共享库。
-
可执行文件:
- Linux/Unix:没有固定后缀,通常是无后缀的可执行文件。
- Windows:后缀为
.exe
。
-
共享库(动态库):
- Linux/Unix:后缀为
.so
(Shared Object)。 - Windows:后缀为
.dll
(Dynamic-Link Library)。
- Linux/Unix:后缀为
-
静态库:
- Linux/Unix:后缀为
.a
。 - Windows:后缀为
.lib
。
- Linux/Unix:后缀为
-
可执行文件:
其他相关文件
-
调试信息文件:
- 生成目标文件时,编译器可以添加调试信息,通常与目标文件结合存储,也可能单独存储为
.dSYM
(macOS)或.pdb
(Windows)。
- 生成目标文件时,编译器可以添加调试信息,通常与目标文件结合存储,也可能单独存储为
-
依赖文件:
- 编译器可能生成
.d
文件,用于记录目标文件与哪些源代码或头文件相关联。
- 编译器可能生成
-
汇编器/链接日志:
- 调试工具可能生成
.log
文件以记录整个编译和链接过程。
- 调试工具可能生成
总结
步骤 | 输入文件 | 输出文件 | 常见后缀 |
---|---|---|---|
预处理 |
.cpp , .h
|
.i , .ii
|
.i , .ii
|
编译 |
.i , .ii , .cpp
|
.s , .asm
|
.s , .asm
|
汇编 |
.s , .asm
|
.o , .obj
|
.o , .obj
|
链接 |
.o , .obj , .a , .so
|
可执行文件或库文件 |
.exe , .so , .dll , .a , .lib
|
根据使用的工具链和编译选项,这些中间文件可以显式生成或在流程中自动处理而不保留。