强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

CMake 从入门到精通:完整教程 / 第 12 章:CMake 预设

第 12 章:CMake 预设

12.1 概述

CMake Presets(CMake 3.19+)通过 JSON 文件定义配置、构建和测试预设,实现团队标准化的构建配置。

CMakePresets.json     ← 版本控制(团队共享)
CMakeUserPresets.json ← 个人配置(gitignore)

12.2 文件结构

{
    "version": 6,
    "cmakeMinimumRequired": {
        "major": 3,
        "minor": 21,
        "patch": 0
    },
    "configurePresets": [],
    "buildPresets": [],
    "testPresets": [],
    "packagePresets": [],
    "workflowPresets": []
}

版本对照表

Preset 版本 CMake 版本 新增特性
1 3.19 基础 configurePresets
2 3.20 buildPresets, testPresets
3 3.21 包含其他预设文件
4 3.23 packagePresets, workflowPresets
5 3.24 环境变量 INCLUDE
6 3.25 更多缓存变量类型

12.3 配置预设(Configure Presets)

12.3.1 基础预设

{
    "version": 6,
    "configurePresets": [
        {
            "name": "default",
            "displayName": "默认配置",
            "description": "默认 Debug 构建",
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/build",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug",
                "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
            }
        }
    ]
}

12.3.2 多配置预设

{
    "version": 6,
    "configurePresets": [
        {
            "name": "base",
            "hidden": true,
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/build/${presetName}",
            "cacheVariables": {
                "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
            }
        },
        {
            "name": "debug",
            "displayName": "Debug",
            "inherits": "base",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug",
                "ENABLE_SANITIZERS": "ON"
            }
        },
        {
            "name": "release",
            "displayName": "Release",
            "inherits": "base",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Release",
                "ENABLE_LTO": "ON"
            }
        },
        {
            "name": "relwithdebinfo",
            "displayName": "Release with Debug Info",
            "inherits": "base",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "RelWithDebInfo"
            }
        }
    ]
}

12.3.3 条件预设

{
    "version": 6,
    "configurePresets": [
        {
            "name": "linux-gcc",
            "displayName": "Linux GCC",
            "condition": {
                "type": "equals",
                "lhs": "${hostSystemName}",
                "rhs": "Linux"
            },
            "generator": "Ninja",
            "cacheVariables": {
                "CMAKE_C_COMPILER": "gcc",
                "CMAKE_CXX_COMPILER": "g++"
            }
        },
        {
            "name": "macos-clang",
            "displayName": "macOS Clang",
            "condition": {
                "type": "equals",
                "lhs": "${hostSystemName}",
                "rhs": "Darwin"
            },
            "generator": "Ninja",
            "cacheVariables": {
                "CMAKE_C_COMPILER": "clang",
                "CMAKE_CXX_COMPILER": "clang++"
            }
        },
        {
            "name": "windows-msvc",
            "displayName": "Windows MSVC",
            "condition": {
                "type": "equals",
                "lhs": "${hostSystemName}",
                "rhs": "Windows"
            },
            "generator": "Visual Studio 17 2022",
            "architecture": {
                "value": "x64"
            }
        }
    ]
}

12.3.4 工具链预设

{
    "version": 6,
    "configurePresets": [
        {
            "name": "arm-cross",
            "displayName": "ARM Cross Compile",
            "toolchainFile": "${sourceDir}/cmake/arm-toolchain.cmake",
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/build-arm",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Release"
            }
        },
        {
            "name": "vcpkg",
            "displayName": "vcpkg Toolchain",
            "toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/build-vcpkg"
        }
    ]
}

12.3.5 配置预设属性

属性 类型 说明
name string 预设名称(必选)
hidden bool 是否隐藏
inherits string/array 继承的预设
condition object 执行条件
displayName string 显示名称
description string 描述
generator string 生成器
architecture object 架构
toolset object 工具集
binaryDir string 构建目录
cmakeExecutable string CMake 可执行文件路径
cacheVariables object 缓存变量
environment object 环境变量
toolchainFile string 工具链文件
installDir string 安装目录

12.4 构建预设(Build Presets)

12.4.1 基础构建预设

{
    "version": 6,
    "buildPresets": [
        {
            "name": "default",
            "configurePreset": "debug"
        },
        {
            "name": "release",
            "configurePreset": "release"
        },
        {
            "name": "release-parallel",
            "configurePreset": "release",
            "jobs": 8,
            "verbose": false
        }
    ]
}

12.4.2 构建预设属性

属性 类型 说明
name string 预设名称
inherits string/array 继承的预设
configurePreset string 关联的配置预设
inheritConfigureEnvironment bool 继承配置环境
jobs int 并行任务数
targets string/array 构建目标
configuration string 构建配置
cleanFirst bool 先清理
verbose bool 详细输出
nativeToolOptions array 原生工具选项

12.4.3 目标特定预设

{
    "version": 6,
    "buildPresets": [
        {
            "name": "libs-only",
            "configurePreset": "debug",
            "targets": ["mylib", "mylib2"]
        },
        {
            "name": "docs",
            "configurePreset": "debug",
            "targets": "docs"
        },
        {
            "name": "tests-only",
            "configurePreset": "debug",
            "targets": "all"
        }
    ]
}

12.5 测试预设(Test Presets)

12.5.1 基础测试预设

{
    "version": 6,
    "testPresets": [
        {
            "name": "default",
            "configurePreset": "debug",
            "output": {
                "outputOnFailure": true,
                "verbosity": "verbose"
            }
        },
        {
            "name": "quick",
            "configurePreset": "debug",
            "filter": {
                "include": {
                    "label": "fast"
                },
                "exclude": {
                    "label": "slow"
                }
            }
        },
        {
            "name": "ci",
            "configurePreset": "release",
            "output": {
                "outputOnFailure": true,
                "outputJUnitFile": "${sourceDir}/test-results.xml"
            }
        }
    ]
}

12.5.2 测试预设属性

属性 类型 说明
name string 预设名称
configurePreset string 关联的配置预设
filter object 测试过滤器
output object 输出选项
execution object 执行选项

12.6 包预设(Package Presets)

{
    "version": 6,
    "packagePresets": [
        {
            "name": "default",
            "configurePreset": "release",
            "generators": ["TGZ", "DEB"],
            "variables": {
                "CPACK_PACKAGE_CONTACT": "[email protected]"
            }
        }
    ]
}

12.7 工作流预设(Workflow Presets)

{
    "version": 6,
    "workflowPresets": [
        {
            "name": "full",
            "steps": [
                { "type": "configure", "name": "release" },
                { "type": "build", "name": "release" },
                { "type": "test", "name": "ci" }
            ]
        }
    ]
}

12.8 变量展开

12.8.1 支持的变量

变量 说明
${sourceDir} 源码目录
${sourceParentDir} 父目录
${sourceDirName} 源码目录名
${presetName} 当前预设名
${generator} 生成器名称
${hostSystemName} 主机系统名
${env:VAR} 环境变量
$penv{VAR} 路径环境变量

12.8.2 环境变量

{
    "version": 6,
    "configurePresets": [
        {
            "name": "custom-env",
            "generator": "Ninja",
            "environment": {
                "CC": "gcc-13",
                "CXX": "g++-13",
                "MY_CUSTOM_PATH": "/opt/custom",
                "PATH": "$penv{PATH}:/opt/tools/bin"
            },
            "cacheVariables": {
                "CMAKE_PREFIX_PATH": "$env{MY_CUSTOM_PATH}"
            }
        }
    ]
}

12.9 条件系统

12.9.1 条件类型

{
    "condition": {
        "type": "equals",
        "lhs": "${hostSystemName}",
        "rhs": "Linux"
    }
}
类型 说明
const 常量布尔值
equals 字符串相等
notEquals 字符串不等
inList 在列表中
notInList 不在列表中
matches 正则匹配
notMatches 正则不匹配
anyOf 任一条件为真
allOf 所有条件为真
not 取反

12.9.2 复合条件

{
    "name": "linux-debug",
    "condition": {
        "type": "allOf",
        "conditions": [
            {
                "type": "equals",
                "lhs": "${hostSystemName}",
                "rhs": "Linux"
            },
            {
                "type": "equals",
                "lhs": "$env{CI}",
                "rhs": "true"
            }
        ]
    }
}

12.10 使用命令

# 列出所有预设
cmake --list-presets
cmake --list-presets=all        # 包括隐藏的
cmake --list-build-presets
cmake --list-test-presets

# 使用配置预设
cmake --preset debug

# 使用构建预设
cmake --build --preset release

# 使用测试预设
cmake --test --preset quick

# 覆盖预设参数
cmake --preset debug -DENABLE_TESTS=ON

12.11 CMakeUserPresets.json

{
    "version": 6,
    "configurePresets": [
        {
            "name": "local-dev",
            "inherits": "debug",
            "binaryDir": "${sourceDir}/build-local",
            "cacheVariables": {
                "ENABLE_CCACHE": "ON"
            },
            "environment": {
                "CCACHE_DIR": "/home/user/.ccache"
            }
        }
    ]
}

CMakeUserPresets.json 应加入 .gitignore

12.12 业务场景

场景:完整的 CI 预设配置

{
    "version": 6,
    "configurePresets": [
        {
            "name": "ci-base",
            "hidden": true,
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/build",
            "cacheVariables": {
                "CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
                "BUILD_TESTING": "ON"
            }
        },
        {
            "name": "ci-linux",
            "inherits": "ci-base",
            "condition": { "type": "equals", "lhs": "${hostSystemName}", "rhs": "Linux" },
            "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
        },
        {
            "name": "ci-windows",
            "inherits": "ci-base",
            "condition": { "type": "equals", "lhs": "${hostSystemName}", "rhs": "Windows" },
            "generator": "Visual Studio 17 2022"
        }
    ],
    "buildPresets": [
        { "name": "ci-build", "configurePreset": "ci-linux", "jobs": 4 }
    ],
    "testPresets": [
        {
            "name": "ci-test",
            "configurePreset": "ci-linux",
            "output": { "outputOnFailure": true }
        }
    ],
    "workflowPresets": [
        {
            "name": "ci",
            "steps": [
                { "type": "configure", "name": "ci-linux" },
                { "type": "build", "name": "ci-build" },
                { "type": "test", "name": "ci-test" }
            ]
        }
    ]
}

12.13 注意事项

问题 说明
版本兼容性 确保 CMake 版本支持 preset 版本
CMakeUserPresets.json 加入 .gitignore
变量展开 $env{} 在配置时展开
generator 必须匹配 build preset 必须与 configure preset 生成器一致
hidden 预设 不能直接使用,只能被继承

12.14 扩展阅读


上一章:第 11 章 — 安装与打包 | 下一章:第 13 章 — 高级特性 →