配置预设(configurePresets)核心字段详解

配置预设,说白了就是告诉 CMake:你要用什么生成器、源码在哪、编译产物放哪。我刚开始接触 Presets 时,以为它就是个花架子,直到在团队里维护了十几个不同平台的构建配置……嗯,那之后我才真正体会到,configurePresets 是整套体系的基石。

这一节,我们逐个拆解最常用的核心字段。你不需要死记硬背,跟着我的思路走一遍,自然就记住了。

3.1 name —— 预设的唯一标识

name 是每个预设的身份证。你在命令行里用 --preset 指定的,就是这个名字。

{
    "version": 6,
    "configurePresets": [
        {
            "name": "default",
            "displayName": "默认配置",
            "description": "适用于本地开发的 Debug 构建",
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/build/default"
        }
    ]
}

我个人习惯用 default 作为最常用的预设名。为什么?因为 CMake 在找不到匹配预设时,会尝试找 default,省得每次都要敲全名。

命名建议:用短横线分隔的 kebab-case,比如 linux-debug、win-release。别用空格或驼峰,命令行里敲起来太累。

3.2 displayName 与 description —— 让人一眼看懂

displayName 是给人看的,description 是补充说明。IDE(比如 CLion、VS Code)会把这些信息展示在预设选择器里。

{
    "name": "ci-linux-gcc",
    "displayName": "CI Linux GCC 构建",
    "description": "用于持续集成环境,使用 GCC 13,开启全部警告"
}

我曾经见过一个项目,所有预设的 description 都写的是 "Default configuration"。你想想看,团队里新来的同事看到这个,跟没写有什么区别?描述要具体,比如「用于 Release 发布,开启 LTO 和 ASAN」——这样别人一看就知道该不该选它。

3.3 generator —— 选择你的构建后端

generator 指定 CMake 用什么工具来生成构建系统。这是最关键的字段之一,选错了,后面全白搭。

生成器 适用平台 特点
Ninja 跨平台 速度快,并行构建,推荐首选
Unix Makefiles Linux/macOS 经典,兼容性好,但速度慢
Visual Studio 17 2022 Windows 配合 MSVC,支持 WinRT/UWP
Xcode macOS 生成 .xcodeproj,适合 Apple 生态

我个人几乎只用 Ninja。为什么?因为它快。我在一个大型 C++ 项目里做过对比:Ninja 比 Makefiles 快了将近 3 倍。尤其是增量编译,Ninja 的依赖分析做得非常精准,改一个头文件不会触发全量重编。

注意:如果你在 Windows 上用 Ninja,记得确保 ninja.exe 在 PATH 里。我曾经因为忘记装 Ninja,排查了半天才发现 CMake 报错说找不到生成器。

3.4 binaryDir —— 构建产物的归宿

binaryDir 指定构建目录,也就是编译出来的 .o、.exe、.lib 放哪。这个路径通常用 ${sourceDir} 做相对定位。

{
    "name": "debug",
    "binaryDir": "${sourceDir}/build/debug"
}

我见过有人把 binaryDir 直接写成 build,结果 Debug 和 Release 的产物混在一起。你想想看,哪天你想清掉 Debug 的缓存,结果把 Release 的也删了……一定要按配置分目录。

常用的目录结构:

  • ${sourceDir}/build/debug
  • ${sourceDir}/build/release
  • ${sourceDir}/build/ci

这样每个预设都有自己的小天地,互不干扰。

3.5 其他常用字段一览

除了上面四个,还有几个字段我几乎每个项目都会用到:

字段 作用 示例
cacheVariables 设置 CMake 缓存变量 "CMAKE_BUILD_TYPE": "Debug"
environment 设置环境变量 "CC": "gcc-13"
toolchainFile 指定工具链文件 "${sourceDir}/cmake/toolchain-arm.cmake"
cmakeExecutable 指定 CMake 路径 "/usr/local/bin/cmake"
核心原则:配置预设只负责「配置阶段」的行为。编译、测试、安装由后续的 buildPresets、testPresets 等负责。别把编译选项塞到 configurePresets 里,那是 buildPresets 的事。

3.6 一个完整的配置预设示例

把上面这些串起来,一个典型的配置预设长这样:

{
    "version": 6,
    "configurePresets": [
        {
            "name": "linux-debug",
            "displayName": "Linux Debug (GCC)",
            "description": "本地开发用,开启调试符号和 AddressSanitizer",
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/build/linux-debug",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug",
                "CMAKE_C_COMPILER": "gcc",
                "CMAKE_CXX_COMPILER": "g++",
                "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
            },
            "environment": {
                "CC": "gcc-13",
                "CXX": "g++-13"
            }
        }
    ]
}

这个预设做了几件事:

  • 用 Ninja 生成器
  • 产物放在 build/linux-debug
  • 设置 Debug 模式,开启 AddressSanitizer
  • 导出 compile_commands.json(给 clangd 或 IDE 用)
  • 强制使用 GCC 13

你只需要在项目根目录执行:

cmake --preset linux-debug

一切自动搞定。不用再敲 -DCMAKE_BUILD_TYPE=Debug 那一长串了。

3.7 知识体系总览

下面这张图帮你理清 configurePresets 的核心逻辑:

configurePresets 核心字段结构 configurePresets name displayName description generator binaryDir cacheVariables environment toolchainFile 核心原则 • name 是唯一标识,displayName/description 给人看 • generator 选 Ninja 通常是最优解 • binaryDir 按配置分目录,避免产物混在一起 • cacheVariables 和 environment 是配置阶段的核心控制手段

从这张图可以看得很清楚:configurePresets 就像一棵树,主干是预设本身,分支是各个字段。每个字段各司其职,组合起来就能精确控制配置阶段的行为。

我的习惯:每新建一个项目,我都会先写一个 default 预设,把 generator 和 binaryDir 定下来。后面再根据需求扩展 Debug、Release、CI 等预设。这样项目从一开始就是「可配置」的,而不是等到需要多环境构建时才手忙脚乱。