1、CMake入门:CMake是什么、为什么需要CMake、CMake与Makefile的关系、CMake的安装与版本选择
1.1 CMake是什么?
CMake,全称是 Cross-platform Make。说白了,它是一个跨平台的构建系统生成器。
你可能会问:「构建系统生成器」是什么鬼?
我换个说法。你写 C++ 代码,最终要变成可执行文件。这个过程需要编译、链接。不同平台(Windows、Linux、macOS)用的编译器不一样,链接方式也不一样。手动写 Makefile ?嗯,小项目还行,项目一大了,那简直是噩梦。
CMake 就是来解决这个问题的。它不直接编译你的代码。它先生成对应平台的构建文件(比如 Linux 下的 Makefile,Windows 下的 Visual Studio 工程文件),然后你再调用 make 或 Visual Studio 去编译。
我个人习惯把 CMake 看作一个「翻译官」。你把项目结构、依赖关系告诉它,它帮你翻译成各个平台能懂的构建指令。
核心要点:CMake 本身不编译代码,它只负责生成构建系统的配置文件。
1.2 为什么需要CMake?
我在项目中遇到过不少团队,还在用手写 Makefile 的方式管理代码。说实话,那滋味真不好受。
为什么需要 CMake?原因有三:
- 跨平台:一套 CMakeLists.txt,Windows、Linux、macOS 通吃。你不需要为每个平台单独维护一套 Makefile。
- 模块化:大型项目动辄几十上百个模块。CMake 的 add_subdirectory、target_link_libraries 能帮你把依赖关系理得清清楚楚。
- 生态:现在主流 C++ 库(Boost、OpenCV、Qt)都支持 CMake。你用 find_package 就能轻松引入第三方库。
你想想看,如果项目有 50 个源文件,分布在 10 个目录里。手写 Makefile 你得维护多少依赖关系?改一个文件,可能就要改一堆 Makefile。用 CMake,你只需要在 CMakeLists.txt 里声明一次源文件列表,剩下的交给它。
我的建议:新项目直接上 CMake。老项目如果还在用 Makefile,也尽早迁移。长痛不如短痛。
1.3 CMake与Makefile的关系
很多人刚接触时容易搞混。我简单梳理一下:
| 对比项 | CMake | Makefile |
|---|---|---|
| 定位 | 构建系统生成器 | 构建系统本身 |
| 输入文件 | CMakeLists.txt | Makefile |
| 输出 | Makefile / 工程文件 | 可执行文件 / 库 |
| 跨平台 | 原生支持 | 需手动适配 |
| 学习曲线 | 中等 | 较陡 |
它们的关系可以用一句话概括:CMake 负责生成 Makefile,make 负责执行 Makefile。
我曾经在一个嵌入式项目里,看到同事直接手写 Makefile 来管理交叉编译。那 Makefile 写了 300 多行,各种 ifeq、else、endif 嵌套,看得我头皮发麻。后来我花了一天时间,用 CMake 重构了构建系统,代码量减少到 50 行,而且可读性高了很多。
避坑指南:不要试图在 CMakeLists.txt 里写复杂的 shell 命令。CMake 有自己的一套语法,用好了很强大。我曾经见过有人把 Makefile 里的 shell 脚本直接搬到 CMake 里,结果平台一换就炸了。
1.4 CMake的安装与版本选择
安装 CMake 其实很简单。但版本选择上,我踩过坑,得跟你聊聊。
安装方式
- Linux:
sudo apt install cmake(Ubuntu/Debian)或sudo yum install cmake(CentOS/RHEL) - macOS:
brew install cmake - Windows:去官网下载安装包,或者用
choco install cmake
我个人习惯用包管理器安装,省事。但要注意,系统自带的版本可能比较老。
版本选择建议
CMake 版本迭代很快。我建议:
- 新项目:用最新稳定版(目前是 3.28+)
- 老项目维护:保持项目原有的版本,不要轻易升级
- 团队协作:统一版本,避免「我本地能编译,你那边不行」的尴尬
为什么会这样?因为 CMake 3.0 和 3.20 的语法有差异。比如 target_sources 命令是 3.1 才引入的。如果你在 CMakeLists.txt 里用了新特性,但队友还在用老版本,编译就会报错。
我的做法:在 CMakeLists.txt 第一行声明最低版本要求:cmake_minimum_required(VERSION 3.16)。这样如果对方版本太低,CMake 会直接提示,而不是编译到一半才报错。
验证安装
装完后,打开终端输入:
cmake --version
你会看到类似这样的输出:
cmake version 3.28.1
嗯,看到版本号,就说明装好了。
小技巧:如果你需要在多个 CMake 版本间切换,可以用 update-alternatives(Linux)或 brew switch(macOS)。Windows 用户可以用环境变量来切换。
1.5 本章小结
这一章我们聊了:
- CMake 是什么:一个跨平台的构建系统生成器
- 为什么需要它:跨平台、模块化、生态好
- 和 Makefile 的关系:CMake 生成 Makefile,make 执行它
- 安装与版本选择:用包管理器安装,新项目用新版,老项目保持稳定
下一章,我们会动手写第一个 CMakeLists.txt。到时候你会发现,原来构建 C++ 项目可以这么简单。