1 Ninja
我们写CMakeLists的初衷,就是为了利用CMake工具将CMakeLists转化成不同平台下的Makefile,以供各个平台编译。但是,CMake的功能不止于此,在构建编译方面,其还可以生成供Ninja工具使用的build.ninja文件,只需要执行类似 cmake .. -G “Ninja”这样的命令即可。
类似于Make工具,在执行ninja命令时,Ninja工具会自动寻找并处理目录下的build.ninja文件,构建并执行编译任务。其优势在于,无论是构建速度还是编译速度,相对于Make都更快,在大型项目中,实测其编译速度至少快10倍。
2 Clion
在面对复杂的项目时,有的时候手写CMakeLists也会比较麻烦,因此,我们可以选择使用Clion来自动构建生成CMakeLists。
Clion是JetBrains旗下的一款用于C/C++开发的IDE,利用它配合VSCode开发,就不必为我们那点薄弱的编译能力和欠缺的CMake/Make知识而烦恼了。
3 库链接的问题
在编译一个可执行程序时,有时会需要链接外部库以获取其提供的函数实现。通常,我们第一反应是从网上下载一个外部库而不是选择自己编译,但这往往会出现一个奇怪的问题,在链接步骤中,链接器无法找到对应的库文件。
这是因为C/C++标准允许每个编译器设计人员以他认为合适的方式实现名称修饰,因此由不同编译器创建的二进制模块(.o 对象代码文件)很可能无法正确的链接。也就是说,两个编译器将为同一个函数生成不同的修饰名称。名称的不同将使链接器无法将一个编译器生成的函数调用与另一个编译器生成的函数定义匹配。
因此,在链接编译模块时,请确保所有对象文件或者库都是由同一个编译器生成的。如果有源代码,通常应该用自己的编译器重新生成源代码来消除链接错误。
3.1 名称修饰
C/C++编译器在编译程序时,会执行一种神奇的操作——名称修饰,其根据函数原型中指定的形参类型对每个函数名进行加密,将函数名称转化为内部表示来描述该接口。这种对原始名称进行的修饰将对参数数目和类型进行编码,添加的符号随函数特征标而异,而修饰时使用的约定随编译器而异。