CMake supports 6 preset types with dedicated JSON schemas:
Configure Presets (configurePresets
)
Define CMake configuration options (generator, toolchain, variables).
Build Presets (buildPresets
)
Specify build parameters (targets, parallelism, configuration type).
Test Presets (testPresets
)
Configure CTest execution (test selection, output formatting).
Package Presets (packagePresets
)
Customize CPack packaging (formats, components).
Workflow Presets (workflowPresets
)
Chain multiple stages (configure → build → test → package).
Install Presets (installPresets
) (New in CMake 3.28)
Define installation paths and components.
Example File Structure (CMakePresets.json
):
{
"version": 6,
"cmakeMinimumRequired": { "major": 3, "minor": 28 },
"configurePresets": [
{
"name": "linux-debug",
"displayName": "Linux Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" }
}
],
"buildPresets": [
{
"name": "build-linux-debug",
"configurePreset": "linux-debug",
"configuration": "Debug"
}
]
}
${variable}
syntax for dynamic values.${sourceDir}
: Project root directory${presetName}
: Current preset’s name${dollar}
: Literal $
characterMacro Example:
{
"configurePresets": [
{
"name": "base",
"cacheVariables": {
"ENABLE_TESTS": "${{TESTING_ENABLED}}"
}
}
]
}
Use -DTESTING_ENABLED=ON
at command line to override.
"inherits": ["parent-preset"]
."condition"
.Conditional Example:
{
"configurePresets": [
{
"name": "windows-x64",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"architecture": "x64"
}
]
}
Orchestrate multi-stage workflows:
{
"workflowPresets": [
{
"name": "full-release",
"steps": [
{ "type": "configure", "name": "win-release" },
{ "type": "build", "name": "build-win-release" },
{ "type": "test", "name": "test-release" },
{ "type": "package", "name": "package-msi" }
]
}
]
}
Execute with:
cmake --workflow --preset=full-release
CMakePresets.json
:{
"version": 6,
"configurePresets": [
{
"name": "base",
"hidden": true,
"cacheVariables": {
"CMAKE_CXX_STANDARD": 20,
"CMAKE_EXPORT_COMPILE_COMMANDS": true
}
},
{
"name": "windows-msvc",
"inherits": "base",
"condition": { "type": "equals", "lhs": "${hostSystemName}", "rhs": "Windows" },
"generator": "Visual Studio 17 2022",
"architecture": "x64",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
},
{
"name": "linux-clang",
"inherits": "base",
"condition": { "type": "equals", "lhs": "${hostSystemName}", "rhs": "Linux" },
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/clang-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_CXX_COMPILER": "clang++"
}
}
],
"buildPresets": [
{
"name": "build-windows",
"configurePreset": "windows-msvc",
"targets": ["ALL_BUILD"]
},
{
"name": "build-linux",
"configurePreset": "linux-clang",
"parallel": 8
}
]
}
Windows:
cmake --preset=windows-msvc
cmake --build --preset=build-windows
Linux:
cmake --preset=linux-clang
cmake --build --preset=build-linux -j 8
JSON Syntax Errors
cmake --list-presets
.Variable Expansion Issues
$
as "${dollar}{variable}"
for non-CMake variables.cacheVariables
over environmentVariables
for cross-platform compatibility.Condition Logic Failures
cmake --debug-output -S . --preset=my-preset
Inheritance Conflicts
inherits
arrays.1. Which of the following are required fields in a configuration-stage preset? (Select two)
A. name
B. binaryDir
C. toolchainFile
D. generator
2. When defining a workflow preset, which stages must be explicitly included? (Select two)
A. configure
B. build
C. test
D. package
3. Which syntax is correct for using environment variables in a preset condition? (Select two)
A. "$env{ENV_VAR}"
B. "${ENV_VAR}"
C. "$ENV{ENV_VAR}"
D. "${env.ENV_VAR}"
4. What is the correct way to inherit presets? (Select two)
A. Use inherits: [parent_preset]
in the preset definition.
B. Use extends: parent_preset
in the preset definition.
C. List multiple presets in the inherits
field to combine their settings.
D. Manually copy all fields from the parent preset.
5. Which fields are unique to the build-stage preset? (Select two)
A. jobs
B. targets
C. configuration
D. verbose
6. How do you enforce a preset to only run on Linux? (Select two)
A. Use condition: "$system.name == 'Linux'"
B. Use condition: "$host.system.name == 'Linux'"
C. Add platforms: ["Linux"]
to the preset.
D. Use a macro like #ifdef LINUX
in the preset.
7. Which statements about cacheVariables
in presets are true? (Select two)
A. They override variables set in CMakeLists.txt
.
B. They are stored in CMakeCache.txt
.
C. They can only be set in configuration-stage presets.
D. They support generator expressions.
8. How do you define a custom macro in a CMake preset? (Select two)
A. Use #define CUSTOM_MACRO value
in the preset file.
B. Define it in the macros
field of the preset.
C. Use set(MACRO value)
in a CMakeLists.txt
file.
D. Use the define
keyword in the preset condition.
9. What is the purpose of the package
stage preset? (Select two)
A. To generate installation scripts.
B. To create distributable packages using CPack.
C. To install built targets to the system.
D. To configure packaging components.
10. Which are valid ways to specify the build directory in a preset? (Select two)
A. binaryDir: "build/${presetName}"
B. buildDir: "build"
C. binaryDir: "$env{BUILD_DIR}"
D. binaryDir: "${sourceDir}/build"
1. A, D
name
and generator
are required for configuration presets. binaryDir
is optional (defaults to ./build
). toolchainFile
is optional.2. A, B
configure
and build
. test
and package
are optional.3. A, C
"$env{ENV_VAR}"
(CMake 3.25+) and "$ENV{ENV_VAR}"
. ${ENV_VAR}
is invalid, and ${env.ENV_VAR}
is incorrect syntax.4. A, C
inherits
field to list parent presets. Multiple inheritance is allowed. extends
is not a valid keyword.5. A, B
jobs
(parallel job count) and targets
(build targets) are build-stage specific. configuration
and verbose
can appear in other stages.6. B, C
condition: "$host.system.name == 'Linux'"
checks the host OS. The platforms
field restricts the preset to specific OSs. $system.name
is invalid.7. B, C
cacheVariables
are stored in CMakeCache.txt
and can only be set during the configuration stage. They do not override CMakeLists.txt
variables set via set(... CACHE)
.8. B, C
macros
field of a preset or via set()
in CMakeLists.txt
. #define
and define
are invalid in presets.9. B, D
package
stage invokes CPack to create packages (e.g., .deb
, .zip
) and configures components. Installation is handled by the install
stage.10. A, D
binaryDir
supports variables (e.g., ${presetName}
) and paths relative to sourceDir
. buildDir
is not a valid field. $env{BUILD_DIR}
requires CMake 3.25+.Question 1: Cross-Platform Build Preset Configuration
Task:
Create a CMakePresets.json
file that:
Ninja
generator for Linux/macOS.Visual Studio 17 2022
for Windows.buildDir
of ${sourceDir}/build
.Requirements:
${host.os}
in conditions.Question 2: Test Preset with Conditional Parameters
Task:
Define a test preset in CMakePresets.json
that:
CTEST_OUTPUT_ON_FAILURE=1
only for Debug configurations.--timeout 300
argument to CTest only for Release configurations.Constraints:
$if
conditions with $lower${presetName}
to detect “debug” in the inherited build preset.Question 3: Multi-Stage Workflow with Component Packaging
Task:
Create a workflow preset named “package-all” in CMakePresets.json
that:
.tar.gz
and .zip
on Linux/macOS, but only .zip
on Windows.libfoo.so.1 → libfoo.so.1.2.3
) are created during installation.$env{PACKAGE_FORMATS}
to define formats per OS.Requirements:
$if
conditions with $host.os
and environment variables.Answer 1: Cross-Platform Build Preset Configuration
{
"version": 6,
"cmakeMinimumRequired": { "major": 3, "minor": 23 },
"configurePresets": [
{
"name": "base-config",
"hidden": true,
"binaryDir": "${sourceDir}/build"
},
{
"name": "linux-macos-config",
"inherits": "base-config",
"generator": "Ninja",
"condition": { "string": { "$host.os": "Linux|Darwin" } }
},
{
"name": "windows-config",
"inherits": "base-config",
"generator": "Visual Studio 17 2022",
"architecture": "x64",
"condition": { "string": { "$host.os": "Windows" } }
}
]
}
Explanation:
base-config
sets binaryDir
to avoid redundancy.linux-macos-config
and windows-config
use condition
with $host.os
to activate on specific OSes.Ninja
is used for Linux/macOS, while Visual Studio is selected for Windows.Answer 2: Test Preset with Conditional Parameters
{
"version": 6,
"cmakeMinimumRequired": { "major": 3, "minor": 23 },
"buildPresets": [
{ "name": "debug-build", "configuration": "Debug" }
],
"testPresets": [
{
"name": "run-tests",
"inherits": "debug-build",
"environment": {
"CTEST_OUTPUT_ON_FAILURE": "$if:$lower{$presetName}~debug:1"
},
"args": [
"$if:$lower{$presetName}~release:--timeout,300"
]
}
]
}
Explanation:
debug-build
to get Debug configuration.CTEST_OUTPUT_ON_FAILURE
is set to 1
only if the inherited build preset name contains “debug”.--timeout 300
is added as a CTest argument for Release configurations.Answer 3: Multi-Stage Workflow with Component Packaging
{
"version": 6,
"cmakeMinimumRequired": { "major": 3, "minor": 23 },
"configurePresets": [ ... ],
"buildPresets": [ ... ],
"testPresets": [ ... ],
"packagePresets": [
{
"name": "package-unix",
"generator": "TGZ",
"configurations": ["Release"],
"environment": { "PACKAGE_FORMATS": "TGZ;ZIP" },
"condition": { "string": { "$host.os": "Linux|Darwin" } }
},
{
"name": "package-win",
"generator": "ZIP",
"condition": { "string": { "$host.os": "Windows" } }
}
],
"workflowPresets": [
{
"name": "package-all",
"steps": [
{ "type": "configure", "name": "linux-macos-config" },
{ "type": "build", "name": "release-build" },
{ "type": "test", "name": "run-tests" },
{
"type": "package",
"name": "$if:$host.os~Windows:package-win,package-unix",
"environment": { "PACKAGE_FORMATS": "$env{PACKAGE_FORMATS}" }
}
]
}
]
}
Explanation:
LIBRARY_OUTPUT_NAME
and uses install(CODE "...")
to create symlinks.package-all
preset chains configure → build → test → package.package-unix
sets PACKAGE_FORMATS
to TGZ;ZIP
, while Windows uses only ZIP
.$env{PACKAGE_FORMATS}
passes formats to CPack via environment variables.These exercises reinforce key Chapter 16 concepts: preset inheritance, OS-specific conditions, workflow chaining, and macro usage.