【Learning CMake Cookbook】关于编译的前景知识

C++基本

关于C++由源文件到可执行文件的基本流程

在学习CMake之前,我们首先要了解C++的完整的编译流程,以使得我们可以更好的理解CMake中一些特定语句的作用,以及其到底对应了编译过程中的哪个阶段。在这里我们指的“编译流程”是宽泛的,即:C/C++从程序源码到最终可执行的二进制文件的变换过程。我们以Linux下为例。

编译流程分为基本的四个步骤,分别是:预处理(Preprocess)、编译(Compile)、汇编(Assemble)、链接(Link)

预处理(Preprocessing)

预处理输入:Source Code -> .c / .cpp / .h / .hpp 文件
预处理输出:Include Header, Expand Macro -> .i / .ii 文件

预处理阶段将输入的源文件中的预处理指令进行处理,简单来说预处理指令就是哪些程序中最前面带有井号“#”的指令,最常用到的如下:

#include  	//用于包含一个头文件
#define   	//定义宏
#ifdef    	//如果已经定义宏,则编译以下的代码直到#endif
#ifndef   	//如果没有定义宏,则编译以下的代码直到#endif
#if       	//如果给定条件为真,则编译以下代码直到#endif
#else		//如果以上的#if条件不为真,则编译以下代码直到#endif
#elif     	//如果以上的#if条件不为真,且当前条件为真,则编译以下代码直到#endif
#endif	  	//终止当前条件分支语句块

另外还有一些可能不太常见的预处理指令(可能只是我不常用)

# 			//空指令,没有任何作用
#undef    	//取消已定义的宏
#error		//停止编译并显式错误信息
#pragma		//
#line		//

在预处理阶段,预处理器通过这些预处理指令,将源文件.c/.cpp/.h/.hpp都转变成.i格式的文件,而这个转换过程,预处理器做了哪些事情呢?(我就举几个简单且主要的例子)

  1. 对于#include指令,预处理阶段将所包含的.h/.hpp统统纳入其被包含的文件,即用整个文件代替这条#include指令
  2. 对于#define A B 将程序中的所有A均替换为B,无论B代表的是数值还是函数
  3. 对于条件编译相关的指令,只保留条件为true内部的语句块,其他部分进行移除(这里我还不是很确定)

所以总体来说,预编译阶段工作可以概括为:对源程序中涉及带“#”的预编译指令的部分进行“替换”,生成一个/一系列没有“包含”、没有“宏定义”、没有”重复编译”的文件,以.i作为文件名后缀。

编译(Compilation)

输入:预处理生成的.i/.ii文件(但是这个具体叫什么呢?)
输出:.s文件(这个叫做汇编语言源程序,不错,就是之后汇编阶段所要输入的文件)

注意:.s(小写)文件与.S(大写)文件还有所不同。其中.s之后的操作只有汇编,而.S文件还需要/允许在汇编之前执行预处理操作

这里没有需要特殊注意的地方,生成的.s或.S文件同样是文本文件,是汇编代码。

汇编(Assemble)

输入:上一步编译生成的汇编码源码
输出:机器码,.o/.obj后缀的文件

这一步中,每一个源文件(特指.c/.cpp)都会产生一个目标文件(.o/.obj)

链接(Linking)

输入:上一步汇编生成的.o文件以及必要的库文件,可以是静态链接库(.a)也可以是动态链接库(.so)
输出:可执行文件(.out文件/Windows下是exe文件)

这一步主要是链接库文件并生成可执行文件,注意:带有main函数的源文件才会生成可执行文件(关于库文件的生成我们在CMake中继续介绍,在此不作深入讨论)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值