第二节:CMake 命令行工具与工程生命周期

第二节:CMake 命令行工具与工程生命周期

一、CMake 工程的完整生命周期

一个标准 CMake 工程,不是"编译一下就完了",而是一个完整闭环:

  1. 配置(Configure)
  2. 生成(Generate)
  3. 构建(Build)
  4. 测试(Test,可选)
  5. 安装(Install,可选)
  6. 打包(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. 这个阶段发生了什么(非常重要)

  1. 解析所有 CMakeLists.txt
  2. 执行:
    • project
    • add_executable
    • add_library
    • target_*
  3. 构建 目标依赖图
  4. 生成底层构建系统文件

⚠️ 注意:
这个阶段不会编译任何代码


七、构建阶段(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
  1. 所有选项都在这里
  2. CMake 的行为是可查的
  3. 不确定 ≠ 猜,而是查

相关推荐
念恒1230637 分钟前
继承(下) (Inheritance)
c++
H Journey2 小时前
C++之 CMake、CMakeLists.txt、Makefile
开发语言·c++·makefile·cmake
研究点啥好呢6 小时前
Github热门项目推荐 | 创建你的像素风格!
c++·python·node.js·github·开源软件
_dindong6 小时前
cf1091div2 C.Grid Covering(数论)
c++·算法
沫璃染墨6 小时前
C++ string 从入门到精通:构造、迭代器、容量接口全解析
c语言·开发语言·c++
6Hzlia6 小时前
【Hot 100 刷题计划】 LeetCode 17. 电话号码的字母组合 | C++ 回溯算法经典模板
c++·算法·leetcode
计算机安禾7 小时前
【数据结构与算法】第36篇:排序大总结:稳定性、时间复杂度与适用场景
c语言·数据结构·c++·算法·链表·线性回归·visual studio
unicrom_深圳市由你创科技7 小时前
做虚拟示波器这种实时波形显示的上位机,用什么语言?
c++·python·c#
无限进步_7 小时前
【C++】电话号码的字母组合:从有限处理到通用解法
开发语言·c++·ide·windows·git·github·visual studio
C++ 老炮儿的技术栈8 小时前
GCC编译时无法向/tmp 目录写入临时汇编文件,因为设备空间不足,解决
linux·运维·开发语言·汇编·c++·git·qt