从源代码到可执行文件.exe的完整过程源代码 (.cpp/.h) ↓ 【预处理】→ 展开宏、包含头文件 ↓ 【编译】→ 生成汇编代码 (.s) ↓ 【汇编】→ 生成目标文件 (.o/.obj) ↓ 【链接】→ 合并目标文件 → 可执行文件 (.exe)linux命令行预处理 gcc -E a.c -o a.i 编译 gcc -s a.i -o a.s 汇编 gcc -c a.s -o a.o 链接 gcc a.o -o a//gcc -o a a.o一、预处理输入.c/.cpp源文件输出.i或.ii预处理后的文本文件预编译过程主要处理那些源代码 文件中的以“#”开始的预编译指令比如“#include”“#define”等主要处理规则如下将所有的“#define”删除并且展开所有的宏定义。处理所有条件预编译指令比如“#if”“#ifdef”“#elif”“#else”“#endif”。处理“#include”预编译指令将被包含的文件插入到该预编译指令的位置。注意这个过程是递归进行的也就是说被包含的文件可能还包含其他文件。把include头文件的内容整个复制粘贴到这里。删除所有的注释“//”和“/**/”。添加行号和文件名标识比如#2“a.c”2以便于编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号。保留所有的#pragma编译器指令因为编译器需要使用它们。二、编译输入.i预处理文件输出.s汇编文件编译过程就是把预处理 完的文件进行一系列词法分析语法分析语义分析代码优化及优化后生成相应的汇编代码文件。代码优化的优缺点优点提高效率缺点多线程下不可控三、汇编输入.s汇编文件输出.o或.obj目标文件二进制机器码汇编过程就是由汇编器将汇编代码转变成机器可以执行的二进制指令。四、链接输入你的所有.o文件 静态库.lib/.a输出最终的.exe可执行文件Windows下或ELFLinux下链接的主要内存就是把各个模块之间相互引用长度部分都处理好使得各个模块之间能够正确的衔接。简单的理解为将各个目标文件链接起来生成最终的可执行文件。链接过程可以具体的分为以下四步合并段和符号表合并多个文件的符号表及各段内容放入一个新的文件中。把所有.o文件的代码段、数据段合并。符号解析在每个文件符号引用引用外部符号的地方找到符号的定义。这就是符号解析。地址和空间分配符号解析成功后为程序分配虚拟地址空间。符号重定位 // 指令段符号重定向就是对.o文件中.text段指令中的无效地址给出具体的虚拟地址或者相对位移偏移量。修正所有跳转指令的偏移量确保程序运行时能跳转到正确的内存地址。链接又分为静态链接动态链接命令行命令行直接调用编译器指令。所有的命令、文件名都需要自己手敲。完全不适用于大一点的工程。MakefileMakefile脚本文件。负责整个工程的编译、链接等规则。所有的规则需要自己指定。写好后只需要输入make就可以调用编译器指令自动直行四个阶段。Makefile 不是用来“编译”的而是用来“调度”编译四阶段的。makefile在一些简单的工程完全可以人工手写但是当工程非常大的时候手写makefile也是非常麻烦的如果换了个平台makefile又要重新修改。Makefile 的麻烦在于你必须手动把每个.cpp依赖了哪些.h全部精确地写在文件里。在大型工程中这种依赖关系呈几何级数增长手写几乎不可能所以才会有相应的工具来自动生成依赖关系。Makefile 为什么编写起来麻烦语法太古老了诞生于 1976 年。它要求严格区分 Tab 和空格变量展开规则晦涩。如果换个平台makefile要重新写。跨平台性很差。必须手动把每个.cpp依赖了哪些.h全部精确地写在文件里。Make 没有函数封装、模块导入这种现代特性容易大量复制粘贴。报错信息晦涩缺乏“人性化”的报错。如果报错Make 只会告诉你Makefile:12: *** missing separator. Stop.ninjaninja与make一样属于同级别的工具功能是对工程文件及进行编译。ninja不像Make那样试图成为一个”万能”的构建系统而是专注于执行构建任务本身。这种设计思路让它避免了大量不必要的功能开销。Ninja在默认情况下就会充分利用多核CPU的性能而且它的任务调度算法相当高效。Ninja是用C编写的而且特别注重减少运行时开销。它的配置文件解析速度极快内存占用也更少。Ninja 舍弃了各种高级功能语法和用法非常简单给它指定好了具体详细要做什么所以启动编译的速度非常快。CMakeCMakeMakefile生成器可以跨平台。可以使用简单的语句来进行描述编译、链接等规则。cmake是一个生成 .ninja 和 .makefile 的工具。因为担心很多人不熟悉makefile文件和ninja文件的写法所以cmake只需要用户通过对源码文件的简单描述就是CMakeLists.txt文件就能自动生成一个project的makefile文件或者ninja文件然后就可以通过ninja或者make进行启动编译了。CMake不直接编译代码而是生成Makefile由Makefile进行编译。命令行执行cmake ..CMake读取你的CMakeLists.txt自动探测你的系统环境编译器路径、库位置。根据你的系统生成对应平台的Makefile或Visual Studio的.sln工程文件。再执行make实际是调用刚刚生成的Makefile去编译。源码 ↓ 【元构建系统】CMake/Meson处理逻辑、环境探测 ↓ 输出构建脚本 【执行后端】Make / Ninja负责真正编译 Make ←→ Ninja 【同级都是执行后端互相替代】 CMake ←→ Meson ←→ Autotools 【同级元构建生成器】生成可执行程序的四个步骤——预处理编译汇编链接_预处理编译4个步骤-CSDN博客关于项目编译工具ninja、make、cmake的区别与优劣 - 我是标同学 - 博客园Ninja为何比Make更快 – N1XON