对于习惯了各种开箱即用的IDE(代表性的Visual Studio)的童鞋来说,初次接触CMake可能会觉得非常的不适应。那么CMake到底是什么呢,有什么用呢?和常见的编译器、生成器又有什么关系呢?还有make/ninja又是什么?
本文只聚焦于解决这些概念问题,而对于具体的CMake用法,CMakeLiats.txt文件写法以及make和nijia用法等不作展开,后续会有其他教程,网上也有海量的教程可以查阅。
一、CMake简介
CMake是一个用于管理项目构建过程的工具,它使用CMakeLists.txt文件来描述项目的组成部分、源代码文件、依赖关系等。他是跨平台的,在 Linux 平台生成构建系统 make 的 Makefile 文件(.makfile),在 Windows 平台生成 Visual Studio 或 MSVC 的工程(.sln,.vcxprog)等。所以具体的构建工作还是需要交给例如 Make,Ninja,MSVC 等这些具体的生成器去执行。
重点:CMake并不直接参与项目的构建编译等工作,而是通过定义编译所需的编译器、源文件等产生标准的构建文档,然后再通过构建文档对于的构建工具如make/nijia/MSVC(cl.exe)等完成构建编译,当然编译器也是必不可少的。
解决了什么呢问题呢?避免了手写makefile等这些文件(对于小项目,其实手写makefile文件也挺方便。但是随着项目的推荐,源文件原来越多的时候,就会变得非常麻烦。另外,没见过谁手写vs的工程项目文件.sln和.vcxprog文件的)
网上一张图以生成makefile的构建结果可以更直观的理解:

从图中可以看出,cmake其实是自动生成了makefile文件,然后用make就可以完成最终的构建编译结果了(前提是安装了make以及一款编译器)。通过配置Cmake,此处makefile文件也可以是ninja的.nijia文件,也可以是vs的.sln、.vcxprog文件,也可以是其他IDE对于的工程管理文件。
此处引用知乎网友“后端知识章”有关cmake的一段介绍,我觉得解释的非常好:
作者:后端知识章
链接:https://www.zhihu.com/question/620368395/answer/3195355942
来源:知乎
对于一个优秀的软件一般都要求其能够做到跨平台运行,所以比如对于同一个 QQ源码需要在多个平台中进行编译,在 Windows 中使用 Visual Studio 编译,MacOS 中使用 Xcode 编译,Linux 中使用 Make+GCC 进行编译。
这时你会发现 QQ 源码需要在不同的平台都搭建一个工程,如果是 Linux 还要修改 Makefile,这还没完呢,如果修改一个编译选项那需要打开每个平台的构建工具进行配置,比如打开 Visual Studio,Xcode,进行配置,所以在构建工具的配置上就需要花费我们不少的精力,工作流如图。

使用 CMake 之后,一切都简单了,我们可以通过 CMake 的 CMakeLists.txt 文件定义好该项目的编译规则,编译选项,等等。然后,选择好构建工具类型,再通过 CMake 生成指定平台构建工具的配置。这样在不同平台下打开各平台的构建工具直接读取 CMake 生成的配置即可,而不必重新的配置,工作流如图。

二、make\nijia\msvc
这三者都是生成器,用CMake可以生成其对应的配置文件,用于后续的构建编译过程
ninja和make都是通过脚本语言指定编译规则,然后调用gcc等编译器实现自动化编译,过程中会通过文件时间戳来进行增量构建.
ninja
ninja 是Google的一名程序员推出的注重速度的构建工具Ninja 是一个专注于速度的小型构建系统。最初是为了对chromium、Swift等进行快速编译构建。设计哲学是通过包含描述依赖关系图的方式提供快速的构建。
其脚本文件后缀为 .ninja
Make
其脚本文件后缀为 .makefile。在有.makefile文件后,直接执行make命令即可按照.makefile的规则自动完成所有的构建编译工作。
MSVC
Visual Studio的构建工具,对应与cl.exe编译器,对应的文件时.sln,.vcxprog这些Visual Studio的工程文件,可以直接用Visual Studio打开。然后继续使用Visual Studio来完成后续工作。
三、CMake使用相关
CMake的使用有命令行和GUI两种。再windows系统下,安装完cmake后会有命令行工具cmake和带界面的工具cmake-GUI。二者功能都相同,都可以通过命令行参数和读取CMakeLists.txt文件来生成对应生成器(make\ninja\vs)文件。
linux下好像也有GUI工具,叫ccmake,但是没有使用过,linux下一般都会直接使用命令行工具吧。
CMake 工作阶段:Configure--->Generate--->Build
配置阶段:
在Configure这一阶段,CMake 将解析源码树顶层的 CMakeLists.txt,并生成一个 CMakeCache.txt 以存储 cache 变量。
对于 CMake-GUI,该阶段由点击 Configure 触发,对于命令行版本的 CMake,该阶段与生成阶段结合在一起。
CMake 打印消息 Configuring done 以表示配置阶段结束。
生成阶段:
在这一阶段,CMake 将根据 CMakeLists.txt 和 CMakeCache.txt 生成构建系统文件。
在 CMake-GUI 中,该阶段由点击 Generate 触发。
CMake 打印消息 Generating done 以表示生成阶段结束。
构建阶段:
这一阶段由构建系统(例如 Linux 中的 Make,Windows 中的 Visual Studio,或者ninja)负责,在这个阶段中将生成被构建项目的目标可执行文件。
两种构建模式:(以make为例)
CMake 支持两种构建模式,分别为 in-source build(源码中构建),out-of-source build(源码外构建):
in-source build 模式
在源文件目录下构建,产生的二进制文件将与源文件生成在一个文件夹里。想要执行就地构建,只需要在源码文件夹运行命令 cmake .,和之前说过的一样,CMake 只是生成了构建工具需要的文件,具体的目标构建还需要构建工具来做,因此还需要运行 cmake --build 执行构建。
out-of-source build 模式
单独创建一个比如 build 文件夹,在该文件夹下构建二进制文件,与源代码文件分开。执行源码外构建,需要运行如下命令。
mkdir build #新建一个build的文件夹
cd ./build #进入这个文件夹
cmake .. #执行 .. ,即CMakeLists.txt所在的文件夹中执行
cmake --build . #构建,根据生成的.makefile文件构建,生成构建结果 "."表示当前目录
一般使用源码外构建,这样不会使得源码文件夹下显得特别乱,也可以通过新建Debug和Release文件来区分不同的编译结果。
其他说明:
关于cmake --build
cmake --build . 会自动选择构建工具("."表示当前目录)。
对于cmake生成的.makefile文件,也可以直接用make工具执行make命令也可以
对于.sln和.vcxprog可以用make --build,也可以用Visual Studio打开.sln这个工程文件,然后用Visual Studio进行生成编译步骤。
对于.ninja没有具体试验过,不过应该和make一样,执行cmake --build或者直接执行ninja命令也可以。
四、总结
综上所述,CMake只是一个管理构建的工具,旨在自动生成对应构建工具(有些地方叫做生成器)如make/visual studio对应的文件。好处是不用为不同的构建工具单独写构建文件,做到了统一管理构建的目的。
也因为CMake不真正参与构建,所以电脑上除了安装cmake软件外,还需要有对应的构建工具(make,ninja,msvs),以及实际的编译器如gcc,clang,cl来让make等使用。
好了,关于CMake的基本概念就介绍至此,希望对有疑惑的童鞋们有帮助。欢迎留言区讨论~
下次再见!!
-概念篇&spm=1001.2101.3001.5002&articleId=145245443&d=1&t=3&u=d454cc1dda4e4babb35cd9201ea0a184)
3万+

被折叠的 条评论
为什么被折叠?



