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

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

3.1 name:每个 Preset 的唯一标识

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

核心规则:
  • 同一个 CMakePresets.json 中,name 不能重复
  • 区分大小写,Debugdebug 是两个不同的 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 编译器"
    }
  ]
}

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

我的建议: name 控制在 20 个字符以内,用连字符分隔。比如 win-msvc-debugmac-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 中引入,增加了 buildPresetstestPresets 的更多功能。

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

版本速查:
  • 版本 1:CMake 3.19+,基础功能
  • 版本 2:CMake 3.20+,增加了 hiddenvendor
  • 版本 3:CMake 3.21+,增加了 conditionworkflowPresets
  • 版本 4:CMake 3.23+,增加了 buildPresetstargets 过滤等

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

这几个字段虽然不强制,但我建议每个 Preset 都写上。尤其是 displayNamedescription,在 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 的构建过程中生效。我在项目中遇到过需要设置 CCCXX 环境变量来指定编译器的情况,用 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-basewin-base,继承底层,添加平台特有配置
  3. 顶层: 具体的构建 Preset,比如 linux-release-gcc,继承中间层,指定构建类型

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

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

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