第二节: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. 不确定 ≠ 猜,而是查

相关推荐
神仙别闹1 小时前
基于 C++ 实现两个有序链表序列的交集
java·c++·链表
hansang_IR3 小时前
【题解】[APIO2023] 赛博乐园 / cyberland
c++·算法·图论
落羽的落羽4 小时前
【AI】快速理解AI应用的相关名词概念
linux·c++·人工智能·python·计算机网络·算法
刚入门的大一新生4 小时前
Linux-进程控制
linux·运维·服务器·c++
刃神太酷啦4 小时前
Redis 进阶核心:持久化 (RDB/AOF)、事务与主从复制全解析----《Hello Redis!》(5)
linux·c语言·数据库·c++·redis·缓存·bootstrap
喜欢吃燃面7 小时前
深入 C++ STL:从 unordered_set与unordered_map到底层哈希表的原理与实现
数据结构·c++·散列表
FlightYe8 小时前
音视频修炼之基础理论(五):AAC格式与解析
android·linux·c++·音视频·aac
ShineWinsu8 小时前
对于MySQL:数据库的操作的解析
linux·数据库·c++·mysql·面试·笔试·库的操作
云小逸9 小时前
C++ 第一阶段:对象、内存与生命周期
开发语言·c++
夜航海图9 小时前
S-57 数据解剖:把一个 ENC 文件拆给你看
c++