cmake --preset: configure and build with CMakePresets.json
- tool
- CMake
- versions
- CMake 3.19+ (presets), CMake 3.25+ (workflow presets), CMake 4.x
- os
- linux, macos, windows
cmake --preset NAME configures a project with the generator, build directory and cache variables stored under that name in CMakePresets.json, so nobody has to remember the long -G ... -B ... -D... line. cmake --build --preset NAME builds it, cmake --list-presets shows the names available, and cmake --workflow --preset NAME (CMake 3.25+) runs configure and build in one command.
A presets file
CMakePresets.json sits next to the top-level CMakeLists.txt. Hidden presets hold shared settings that others inherit:
{
"version": 6,
"configurePresets": [
{ "name": "base", "hidden": true, "generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}" },
{ "name": "debug", "displayName": "Debug with tests", "inherits": "base",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "WITH_TESTS": "ON" } },
{ "name": "release", "displayName": "Release", "inherits": "base",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "WITH_TESTS": "OFF" } }
],
"buildPresets": [
{ "name": "debug", "configurePreset": "debug" },
{ "name": "release", "configurePreset": "release" }
],
"workflowPresets": [
{ "name": "release", "steps": [
{ "type": "configure", "name": "release" },
{ "type": "build", "name": "release" } ] }
]
}Run it
cat > CMakeLists.txt <<'EOF'
cmake_minimum_required(VERSION 3.25)
project(demo NONE)
message(STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} WITH_TESTS=${WITH_TESTS}")
add_custom_target(hello ALL COMMAND ${CMAKE_COMMAND} -E echo "built $<CONFIG>" COMMENT "Running hello")
EOF
cat > CMakePresets.json <<'EOF'
{
"version": 6,
"configurePresets": [
{ "name": "base", "hidden": true, "generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}" },
{ "name": "debug", "displayName": "Debug with tests", "inherits": "base",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "WITH_TESTS": "ON" } },
{ "name": "release", "displayName": "Release", "inherits": "base",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "WITH_TESTS": "OFF" } }
],
"buildPresets": [
{ "name": "debug", "configurePreset": "debug" },
{ "name": "release", "configurePreset": "release" }
],
"workflowPresets": [
{ "name": "release", "steps": [
{ "type": "configure", "name": "release" },
{ "type": "build", "name": "release" } ] }
]
}
EOF
cmake() { uv run -q --no-project --python 3.13 --with cmake==4.4.4 --with ninja==1.13.0 cmake "$@"; }
cmake --list-presets
echo '--- configure and build debug'
cmake --preset debug | grep CMAKE_BUILD_TYPE
cmake --build --preset debug
ls build
echo '--- workflow release'
cmake --workflow --preset release | grep -e 'step' -e CMAKE_BUILD_TYPE -e builtOutput
Available configure presets: "debug" - Debug with tests "release" - Release --- configure and build debug -- CMAKE_BUILD_TYPE=Debug WITH_TESTS=ON [1/1] Running hello built Debug debug --- workflow release Executing workflow step 1 of 2: configure preset "release" -- CMAKE_BUILD_TYPE=Release WITH_TESTS=OFF Executing workflow step 2 of 2: build preset "release" built Release
The base preset is not listed because it is hidden, and each preset gets its own directory under build/ through the ${presetName} macro.
Commands
| Command | Does |
|---|---|
| cmake --list-presets | list configure presets (add =all for build, test, package and workflow presets) |
| cmake --preset NAME | configure with the configure preset NAME |
| cmake --build --preset NAME | build with the build preset NAME (its configurePreset picks the directory) |
| ctest --preset NAME | run tests with a test preset |
| cmake --workflow --preset NAME | run every step of a workflow preset in order (CMake 3.25+) |
| cmake --preset NAME -DVAR=value | override one cache variable of the preset |
Errors you may see
CMake Error: No such configure preset in DIR: "name"means the name is wrong or you are not in the directory holdingCMakePresets.json; CMake prints the available presets right after the error.- A file whose
versionis newer than your CMake is rejected as unsupported: lower the version or upgrade CMake. - A non-hidden build preset must name its
configurePreset, directly or throughinherits, because that is where CMake finds the build directory. - Presets only replace the command line: the project still fails with No CMAKE_C_COMPILER could be found when no compiler exists.
Pitfalls
- Macros in binaryDir.
${sourceDir}and${presetName}are preset macros expanded by CMake, not shell variables; keep them inside the JSON string. - Machine-specific paths. Compiler locations and local toolchains belong in
CMakeUserPresets.json, which each developer keeps out of version control. - IDE support. Visual Studio, VS Code (CMake Tools) and CLion read the same file, so a preset that works on the command line appears in the IDE too.
FAQ
What is the difference between CMakePresets.json and CMakeUserPresets.json?
CMakePresets.json is committed with the project and holds presets everyone shares. CMakeUserPresets.json is for one developer's local presets, should not be committed, and implicitly includes CMakePresets.json so it can inherit from its presets.
Which version number should the presets file use?
The lowest version that has the features you use, because CMake refuses files with a newer schema than it supports. Version 3 (CMake 3.21) is enough for configure and build presets with an optional binaryDir; workflow presets need version 6 (CMake 3.25).
Can I still pass -D options when I use a preset?
Yes. Options given on the command line after --preset override the preset's cacheVariables, for example cmake --preset release -DWITH_TESTS=ON.