3、基础配置项:name、hidden、vendor、version 等顶层字段详解

咱们直接切入正题。CMake Presets 的顶层字段,说白了就是整个配置文件的「身份证」和「开关」。我刚开始接触 Presets 时,觉得这些字段不就是填个名字嘛,有啥好讲的?结果有一次在团队里因为 vendor 字段没写对,导致 CI 工具解析失败,折腾了大半天。嗯,从那以后我再也不敢小看这些基础配置了。

3.1 name:每个 Preset 的唯一标识

name 字段是必须的。它就像每个人的身份证号,在一个文件中不能重复。我个人习惯用 「平台-构建类型-编译器」 的命名方式,比如 linux-release-gcc。这样一看名字就知道这个 Preset 是干啥的。

核心规则:
  • 同一个 CMakePresets.json 中,name 不能重复
  • 区分大小写,Debug 和 debug 是两个不同的 Preset
  • 建议使用小写字母和连字符,避免空格和特殊字符
{
  "version": 3,
  "configurePresets": [
    {
      "name": "linux-release-gcc",
      "displayName": "Linux Release (GCC)",
      "description": "面向 Linux 平台的 Release 构建,使用 GCC 编译器"
    },
    {
      "name": "linux-debug-clang",
      "displayName": "Linux Debug (Clang)",
      "description": "面向 Linux 平台的 Debug 构建,使用 Clang 编译器"
    }
  ]
}

你看,displayName 和 description 是给人看的,name 是给机器用的。我在项目中遇到过有人把 name 写得特别长,比如 "This is my special debug build for testing on Windows with MSVC"。说实话,这虽然能跑,但你在命令行里敲 cmake --preset 的时候,补全起来会疯掉的。

我的建议: name 控制在 20 个字符以内,用连字符分隔。比如 win-msvc-debug、mac-clang-release。

3.2 hidden:让 Preset 隐身

hidden 字段是个布尔值,默认是 false。把它设为 true 后,这个 Preset 就不会出现在 cmake --list-presets 的输出里。但注意,它仍然可以被其他 Preset 通过 inherits 继承。

为什么会需要隐藏 Preset?说白了,就是用来做「基类」的。我经常定义一个 common-flags 的隐藏 Preset,里面放所有平台都通用的编译选项,然后让各个平台的 Preset 去继承它。

{
  "configurePresets": [
    {
      "name": "common-base",
      "hidden": true,
      "cacheVariables": {
        "CMAKE_CXX_STANDARD": "17",
        "CMAKE_CXX_EXTENSIONS": "OFF"
      }
    },
    {
      "name": "linux-debug",
      "hidden": false,
      "inherits": "common-base",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Debug"
      }
    }
  ]
}
注意: 我曾经犯过一个错——把 hidden 设为 true 后,忘了在别的 Preset 里 inherits 它。结果这个 Preset 就真的「消失」了,谁也找不到。所以隐藏 Preset 一定要有被继承的地方,否则就是死代码。

3.3 vendor:给工具链留个「后门」

vendor 字段是个 JSON 对象,用来存放 CMake 官方不直接支持的、特定于某个工具链或 IDE 的配置。比如 Visual Studio、CLion、Qt Creator 这些工具,它们可能会在 vendor 里放一些自己的扩展字段。

我个人的经验是:尽量少用 vendor。因为一旦用了,你的 Preset 文件就和某个特定工具绑定了。换到另一个 IDE 或者 CI 环境,这些配置可能就失效了。

工具 vendor 常见用途
Visual Studio 指定解决方案配置名称、平台工具集
CLion 工具链路径、环境变量
Qt Creator Kit 名称、Qt 版本路径
{
  "configurePresets": [
    {
      "name": "vs2022-debug",
      "vendor": {
        "microsoft.com/VisualStudioSettings": {
          "platformToolset": "v143",
          "configurationType": "Debug"
        }
      }
    }
  ]
}
避坑指南: 如果你要在团队里共享 Preset 文件,建议把 vendor 相关的配置单独放到 CMakeUserPresets.json 里。这样每个人的 IDE 配置不会互相干扰。

3.4 version:版本号决定你能用啥

version 字段指定了 Preset 文件的格式版本。目前主流的是 版本 3(CMake 3.21+),版本 4 在 CMake 3.23 中引入,增加了 buildPresets 和 testPresets 的更多功能。

我建议直接写 "version": 3,除非你明确需要版本 4 的新特性。为什么?因为版本 3 的兼容性最好,大多数 CI 环境和团队成员的 CMake 版本都能支持。

版本速查:
  • 版本 1:CMake 3.19+,基础功能
  • 版本 2:CMake 3.20+,增加了 hidden、vendor
  • 版本 3:CMake 3.21+,增加了 condition、workflowPresets
  • 版本 4:CMake 3.23+,增加了 buildPresets 的 targets 过滤等

3.5 其他顶层字段:displayName、description、environment

这几个字段虽然不强制,但我建议每个 Preset 都写上。尤其是 displayName 和 description,在 cmake --list-presets 时能显示出来,方便团队成员快速理解每个 Preset 的用途。

{
  "configurePresets": [
    {
      "name": "win-msvc-release",
      "displayName": "Windows MSVC Release",
      "description": "面向 Windows 平台的 Release 构建,使用 MSVC 编译器,开启 LTO",
      "environment": {
        "MY_CUSTOM_VAR": "some_value"
      }
    }
  ]
}

environment 字段可以设置环境变量,这些变量只在当前 Preset 的构建过程中生效。我在项目中遇到过需要设置 CC 和 CXX 环境变量来指定编译器的情况,用 environment 就比在系统层面改要干净得多。

3.6 知识体系总览

下面这张图把顶层字段的关系梳理清楚了。你看,name 是核心,hidden 控制可见性,vendor 是扩展接口,version 决定能力边界,其他字段则是辅助信息。

CMake Presets 顶层字段结构 CMakePresets.json name 唯一标识,必须字段 hidden 布尔值,控制可见性 vendor 工具链扩展配置 version 格式版本号 displayName 人类可读的名称 description 详细描述信息 environment 临时环境变量 红色=核心字段 | 橙色=控制字段 | 绿色=扩展字段 | 紫色=版本字段 | 蓝色=辅助字段 注意:hidden 为 true 的 Preset 不会出现在 --list-presets 中,但可被继承

3.7 实战建议:如何组织你的 Preset 文件

最后,我分享一个我在实际项目中用的组织方式。说白了就是「分层设计」:

  1. 底层: 定义几个 hidden: true 的基类 Preset,放通用配置(C++ 标准、通用编译选项)
  2. 中间层: 按平台分,比如 linux-base、win-base,继承底层,添加平台特有配置
  3. 顶层: 具体的构建 Preset,比如 linux-release-gcc,继承中间层,指定构建类型

这样改起来特别方便。比如有一天你想给所有 Linux 构建加一个 -Wall 选项,只需要改 linux-base 这一个地方就行。我曾经在接手一个老项目时,看到人家把同样的编译选项复制粘贴了 20 多遍,改一次要改 20 多个地方……嗯,那滋味可不好受。

一句话总结: name 是身份,hidden 是开关,vendor 是后门,version 是能力。把这四个字段用好,你的 Preset 文件就成功了一半。

公众号:蓝海资料掘金营,微信deep3321