第二节:CMake 命令行工具与工程生命周期
一、CMake 工程的完整生命周期
一个标准 CMake 工程,不是"编译一下就完了",而是一个完整闭环:
- 配置(Configure)
- 生成(Generate)
- 构建(Build)
- 测试(Test,可选)
- 安装(Install,可选)
- 打包(Package,可选)
CMake 的命令行工具,正是围绕这 6 个阶段设计的。
二、cmake 命令的三种基本调用形式
text
cmake [options] <source-dir>
cmake [options] <build-dir>
cmake [options] -S <source-dir> -B <build-dir>
1. 推荐且现代的形式(必须掌握)
bash
cmake -S . -B build
语义非常清晰:
-S:Source Tree(源码树)-B:Build Tree(构建树)
这是 CMake 官方推荐、IDE 默认、工业界标准的写法。
三、源文件树(Source Tree)
1. 定义
源文件树是指:
包含顶级
CMakeLists.txt的目录及其子目录结构
特点:
- 存放源码
- 存放 CMake 配置
- 不应包含任何构建产物
2. 顶级标识
一个目录是否是源文件树的根,只有一个标准:
是否包含顶级
CMakeLists.txt
四、构建树(Build Tree)
1. 定义
构建树是 CMake 为一次"配置实例"创建的工作目录,用于存放:
- Makefile / Ninja 文件
- 中间文件(.o / .obj)
- 最终产物
CMakeCache.txt
2. 构建树的核心文件
(1)CMakeCache.txt
- 记录所有缓存变量
- 构建配置的"快照"
- 删除 build 目录 = 完全重来
(2)CMakeFiles/
- CMake 的内部状态
- 不要手改
- 不要提交版本控制
五、源内构建 vs 源外构建(再强调一次)
1. 源内构建
bash
cmake .
问题:
- 构建文件污染源码
- 不可维护
- 无法并行多配置
2. 源外构建(唯一正确姿势)
bash
cmake -S . -B build
这是工程级别的强制约定,不是建议。
六、生成构建系统(Configure + Generate)
1. 命令
bash
cmake -S . -B build
2. 这个阶段发生了什么(非常重要)
- 解析所有
CMakeLists.txt - 执行:
projectadd_executableadd_librarytarget_*
- 构建 目标依赖图
- 生成底层构建系统文件
⚠️ 注意:
这个阶段不会编译任何代码
七、构建阶段(Build)
1. 推荐命令(跨平台)
bash
cmake --build build
等价于:
- Makefile →
make - Ninja →
ninja - Visual Studio →
msbuild
2. 为什么推荐 cmake --build
原因只有一个:
它屏蔽了底层构建系统差异
你不需要关心当前是 Make 还是 Ninja。
八、测试阶段(CTest)
1. 前提条件
只有在 CMakeLists.txt 中:
cmake
include(CTest)
add_test(...)
测试才会被注册。
2. 执行测试
bash
ctest
或:
bash
cmake --build build --target test
本质:
- CTest 只是一个测试调度器
- 实际运行的是你注册的可执行程序
九、安装阶段(Install)
1. 命令
bash
cmake --install build
或传统方式:
bash
make install
2. 安装的本质
安装 = 拷贝
- 可执行文件
- 库文件
- 头文件
- 配置文件
到:
text
CMAKE_INSTALL_PREFIX
3. 安装与构建的关系
- 构建:给"开发者自己用"
- 安装:给"其他项目 / 用户用"
这是两个完全不同的阶段。
十、打包阶段(CPack)
1. 前提
CMakeLists.txt 中包含:
cmake
include(CPack)
2. 命令
bash
cpack
或:
bash
cmake --build build --target package
3. 核心原则
CPack 不直接打包 build 产物,而是:
打包 install 阶段收集的文件
所以:
不会 install,就无法正确 package
十一、CMake 的脚本模式(Script Mode)
1. 命令
bash
cmake -P script.cmake
2. 特点
- 不生成构建系统
- 不产生目标
- 不涉及编译
3. 使用场景
- 文件拷贝
- 环境检测
- 自动化部署
- 构建辅助逻辑
十二、CMake 的命令模式(-E)
1. 命令
bash
cmake -E <subcommand>
2. 作用
提供跨平台统一命令,例如:
- rm
- cp
- mkdir
- echo
目的只有一个:
避免 shell 命令的跨平台不一致
十三、查看帮助
bash
cmake --help
- 所有选项都在这里
- CMake 的行为是可查的
- 不确定 ≠ 猜,而是查