CMake教程(零)- C++ 的编译流程
C++ 编译流程概述
如下图所示,C++文件的编译流程主要可以分为4个步骤:
- 预处理
- 编译
- 汇编
- 链接
每个步骤的输入输出文件都各不相同。
预处理
在预处理阶段,预处理器会对源文件中的伪指令(以#
开头的指令)和特殊符号进行处理。
伪指令包括:宏定义指令
#define
;条件编译指令#if
;头文件包含指令#include
等
预处理器有如下规则:
- 删除所有
#define
,并展开所有宏定义 - 处理所有条件编译指令,如
#if
、#ifdef
等 - 处理头文件包含指令
#include
,将被包含的文件插入到该编译指令的位置,并以递归的方式处理包含文件可能包含的其他文件。 - 删除所有注释
//
、/**/
- 添加行号和文件标识,方便编译器产生调试用的信息
- 保留有所
#pragma
编译器指令
直接执行g++ <源文件>
会隐藏掉编译的中间过程,可以通过执行下面的指令来告诉g++只进行预处理并输出指定文件名的.i
文件。
g++ -E test.cpp -o test.i
编译
编译过程就是把预处理完的文件进行一系列的词法分析、语法分析、语义分析及优化,最后生成汇编代码.s
文件。通过下面指令可以告诉g++只进行编译阶段并根据输入的.i
文件生成对应的汇编文件。
g++ -S test.i -o test.s
汇编
汇编就是将汇编代码转变成及其可以执行的二进制代码。
g++ -c test.s -o test.o
链接
链接阶段主要的作用是解决多个文件之间符号引用的问题。详细讲会比较复杂,简单来说就是将目标文件和库文件,包括静态库和动态库,链接起来,生成对应的可执行文件。
静态库和动态库的区别可以参考我的另一篇文章《CMake教程(二)- 添加静态库文件和动态库文件》