Wiki
CMakePresets and Build Installation
Existing English translations were reused. 31 current source blocks remain in Simplified Chinese, without triggering paid translation.
CMakePresets.json Used to store commonly used CMake configurations. The problem it solves is: avoid having to manually write a long string of cmake -S ... -B ... -G ... -D... commands every time.
The template's CMakePresets.json is as follows:
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 22,
"patch": 0
},
"configurePresets": [
{
"name": "base",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/${presetName}"
}
},
{
"name": "linux-debug",
"displayName": "Linux Debug",
"inherits": "base",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
},
"cacheVariables": {
"BUILD_SHARED_LIBS": "ON"
}
},
{
"name": "linux-release",
"displayName": "Linux Release",
"inherits": "linux-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "windows-debug",
"displayName": "Windows GCC Debug",
"inherits": "base",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"cacheVariables": {
"CMAKE_C_COMPILER": "gcc",
"CMAKE_CXX_COMPILER": "g++",
"BUILD_SHARED_LIBS": "OFF"
}
},
{
"name": "windows-release",
"displayName": "Windows GCC Release",
"inherits": "windows-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
}
],
"buildPresets": [
{
"name": "linux-debug",
"configurePreset": "linux-debug"
},
{
"name": "linux-release",
"configurePreset": "linux-release"
},
{
"name": "windows-debug",
"configurePreset": "windows-debug"
},
{
"name": "windows-release",
"configurePreset": "windows-release"
}
],
"testPresets": [
{
"name": "linux-debug",
"configurePreset": "linux-debug",
"output": {
"outputOnFailure": true
}
},
{
"name": "linux-release",
"configurePreset": "linux-release",
"output": {
"outputOnFailure": true
}
},
{
"name": "windows-debug",
"configurePreset": "windows-debug",
"output": {
"outputOnFailure": true
}
},
{
"name": "windows-release",
"configurePreset": "windows-release",
"output": {
"outputOnFailure": true
}
}
]
}
后面逐项解释时,很多地方继续用 linux-debug 举例。Windows 对应使用 windows-debug,Release 则分别使用 linux-release、windows-release;当前系统可选择的配置由 condition 决定。
1.root field
1.1.version
"version": 3
indicates CMakePresets.json the file format version, not the project version.
What can be filled in:
| 值 | 含义 |
|---|---|
1、2、3、... |
CMake preset 文件格式版本 |
3 |
本模板使用的版本,CMake 3.21 起支持;本工程统一要求 CMake 3.22 及以上 |
6 |
CMake 3.25 起支持,新增打包预设和工作流预设等功能 |
Note:
- This is not
cmake_template's version number. - To be compatible with older CMake, lower
version, but some fields may no longer be usable. - If the local CMake is very new, you do not necessarily have to use the highest preset version; as long as it is sufficient.
本模板只使用格式 3 已支持的配置、构建、测试和平台条件字段,因此 Ubuntu 22.04 的 CMake 3.22.1 就能读取。格式与字段说明见 CMake 3.22 预设文档;格式 6 的新增功能见 CMake 3.25 预设文档。
1.2.cmakeMinimumRequired
"cmakeMinimumRequired": {
"major": 3,
"minor": 22,
"patch": 0
}
声明工程要求的最低 CMake 版本。CMake 还会单独检查自己是否支持前面的预设格式版本,两个条件都要满足。
What can be filled in:
| 字段 | 示例 | 含义 |
|---|---|---|
major |
3 |
主版本号 |
minor |
22 |
次版本号 |
patch |
0 |
补丁版本号 |
本模板以 CMake 3.22 为兼容基线,顶层 CMakeLists.txt 同样写为:
cmake_minimum_required(VERSION 3.22)
二者保持一致。Ubuntu 22.04 可以直接使用 CMake 3.22.1;如果把旧模板改为这个配置,需要同时修改顶层最低版本、预设格式 version 和这里的 minor 三处,原有的 Debug / Release 预设、目录和 Ninja 生成器保持不变。
2.configurePresets
configurePresets is the preset for the "configuration phase".
Commands corresponding to the configuration phase:
cmake --preset linux-debug
It is equivalent to telling CMake:
- Which generator to use.
- Where the build directory is.
- What the build type is.
- Where the install directory is.
- Whether to generate
compile_commands.json.
2.1.name
"name": "linux-debug"
A machine-readable name for the preset.
What can be filled in:
| Naming | Description |
|---|---|
linux-debug |
Debug preset for this template |
linux-release |
Release preset for this template |
debug |
This is also possible, but not as clear as linux-debugclear |
gcc-debug |
If distinguishing compilers, you can name them like this |
clang-debug |
If adding a Clang preset, you can name it like this |
Requirements:
- 同一个数组里不能重名。
buildPresets里的configurePreset要引用这里的名字。- 命令行使用的就是这个名字。
Example:
cmake --preset linux-debug
2.2.displayName
"displayName": "Linux Debug"
A human-readable name, mainly used for display in IDEs, such as the preset list in VSCode CMake Tools.
What can be filled in:
| Writing style | Description |
|---|---|
Linux Debug |
Clear |
Linux Release |
Clear |
Debug |
OK, but no platform distinction |
Fedora GCC Debug |
If there are many presets, you can be more specific |
This field does not affect the actual build logic.
2.3.generator
"generator": "Ninja"
Specify what build system files CMake should generate.
Linux common optional values:
| Value | Description |
|---|---|
Ninja |
Recommended, fast, clean output, suitable for VSCode CMake Tools |
Unix Makefiles |
Traditional Makefile workflow |
Ninja Multi-Config |
Multi-config Ninja, can manage Debug / Release simultaneously |
This template only supports Linux and uses Ninja, so it is fixed as:
"generator": "Ninja"
If using Unix Makefiles, the build command can still be used:
cmake --build --preset linux-debug
But the underlying layer is no longer Ninja.
2.4.binaryDir
"binaryDir": "${sourceDir}/build/linux-debug"
Specify the build directory.
What can be filled in:
| Syntax | Description |
|---|---|
${sourceDir}/build/linux-debug |
Recommended; build artifacts stay in the project's build subdirectory |
${sourceDir}/build/debug |
Also acceptable, but less clear than linux-debug. |
/tmp/my-build |
Can be placed outside the project, but is not suitable as a template default |
Common macros:
| Macro | Meaning |
|---|---|
${sourceDir} |
Project source root directory |
${presetName} |
Current preset name |
${sourceParentDir} |
Parent directory of the source root directory |
It can also be written as:
"binaryDir": "${sourceDir}/build/${presetName}"
This way linux-debug is automatically generated to:
build/linux-debug
This template explicitly writes out the table of contents to make it more intuitive for beginners.
2.5.cacheVariables
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/linux-debug"
}
cacheVariablesEquivalent to the -D parameter on the command line.
For example:
"CMAKE_BUILD_TYPE": "Debug"
Equivalent to:
-DCMAKE_BUILD_TYPE=Debug
3.Common cache variables
3.1.CMAKE_BUILD_TYPE
"CMAKE_BUILD_TYPE": "Debug"
Build type used in single-configuration generators.Ninja and Unix Makefiles are both common single-configuration generators.
What can be filled in:
| Value | Effect |
|---|---|
Debug |
Debug build, usually with -g, less optimization |
Release |
Release build, usually with optimization enabled |
RelWithDebInfo |
Optimization + debug information |
MinSizeRel |
Optimize for size |
Common choices:
| Scenario | Recommended |
|---|---|
| Writing code, debugging breakpoints | Debug |
| Release, performance testing | Release |
| Performance testing but want to retain symbols | RelWithDebInfo |
| Embedded or size-sensitive | MinSizeRel |
3.2.CMAKE_EXPORT_COMPILE_COMMANDS
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
Generate compile_commands.json.
What can be filled in:
| value | role |
|---|---|
ON |
Generate compile_commands.json |
OFF |
Do not generate |
compile_commands.json Record the actual compilation command for each source file.clangd、VSCode, and many static analysis tools use it to obtain information such as include paths, macro definitions, and compilation standards.
It is recommended to enable this by default in the template:
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
3.2.1.Let clangd find compile_commands.json
Just generate compile_commands.json, it does not mean that clangd will definitely find it automatically.
Before using this approach in VSCode, you need to install the official LLVM clangd extension. CMake Tools is responsible for configuration, building, and selecting targets, while clangd is responsible for code completion, goto definition, semantic checking, and other editing features; they are not the same extension.
This template sets the Debug build directory to:
build/linux-debug/
Therefore, execute:
cmake --preset linux-debug
Afterwards, the compilation database is located at:
build/linux-debug/compile_commands.json
By default, clangd searches upward level by level starting from the directory containing the current source file compile_commands.jsonIt can usually find the database in the project root directory or the directory directly under build/ but it may not continue searching preset directories with multiple levels such as build/linux-debug/.
If clangd does not find the database, it enters fallback mode and analyzes source files using only a small set of default parameters. In this case, even if CMake can compile normally, the following may still occur in VSCode:
- 项目头文件显示找不到。
- Eigen、OpenCV 等第三方库显示找不到。
- C++ 标准识别错误,例如工程使用 C++20,clangd 却按照 C++17 分析。
- 跳转定义、自动补全和错误提示不准确。
It is recommended to create in the project root directory .clangd:
CompileFlags:
CompilationDatabase: build/linux-debug
The directory structure will become:
.
├── .clangd
├── CMakeLists.txt
├── CMakePresets.json
├── build/
│ └── linux-debug/
│ └── compile_commands.json
└── src/
CompilationDatabase Use paths relative to the directory where .clangd is located, so do not write an absolute path on a user's computer. This file only stores project-wide configuration and can be committed to Git.
Note, .clangd does not generate a compilation database. The first time you use the project, or after modifying CMakeLists.txt、 compilation options, dependencies, and presets, you still need to rerun:
cmake --preset linux-debug
Or select linux-debug in VSCode CMake Tools and click Configure.
If .clangd does not take effect immediately after creation, you can run the following in the VSCode Command Palette:
clangd: Restart language server
You can also close and reopen the current .cpp file.
If the Microsoft C/C++ extension is also installed and the editor shows two duplicate sets of error prompts, you can keep the GDB debugging functionality provided by the extension while disabling its IntelliSense, letting clangd handle code analysis independently. This is a personal VSCode setting and does not need to be written into the CMake template.
Windows 的数据库位于 build/windows-debug/compile_commands.json,因此 .clangd 要对应改成:
CompileFlags:
CompilationDatabase: build/windows-debug
CMAKE_EXPORT_COMPILE_COMMANDS 在 Ninja 生成器下适用,两种平台都保持使用 Ninja。Windows 中 clangd 查询 GCC 标准库路径的配置见 Windows开发环境搭建与测试。
3.2.2.Check whether clangd is actually taking effect
Open in VSCode:
查看 -> 输出 -> clangd
Normally, similar content should be seen:
Loaded compilation database from .../build/linux-debug/compile_commands.json
Compile command from CDB is: ...
If you see:
Failed to find compilation database
command clangd fallback
This indicates that clangd still has not read the compilation database. Check sequentially:
- Whether the one opened by VSCode is the project root directory.
.clangdWhether it is located in the project root directory.- Whether it has already been executed
cmake --preset linux-debug. build/linux-debug/compile_commands.jsonWhether it actually exists..clangdWhether the directory name inbinaryDiris completely consistent with
If it can be used directly in the system terminal, clangdyou can also check a single source file:
clangd --check=src/main.cpp
The output should show that it loaded build/linux-debug/compile_commands.json, and use the include paths, macro definitions, and C++ standard generated by CMake.
3.2.3.Use the Release database
If you want clangd to analyze according to the Release configuration, you can change it to:
CompileFlags:
CompilationDatabase: build/linux-release
And generate the corresponding database first:
cmake --preset linux-release
Daily development typically uses build/linux-debug. Do not let both .clangd point to a build directory that has not yet been generated or has already expired.
3.3.CMAKE_INSTALL_PREFIX
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/linux-debug"
Specify the installation directory.
What can be filled in:
| Usage | Description |
|---|---|
${sourceDir}/install/linux-debug |
Debug installation directory for this template |
${sourceDir}/install/linux-release |
Release installation directory for this template |
/usr/local |
System-level installation path, requires privileges, not suitable as template default |
/opt/my_project |
System-level or deployment path |
This template places the installation directory inside the project to make it easy to learn from and delete.
After installation, run:
./install/linux-debug/bin/cmake_template
3.4.BUILD_SHARED_LIBS
当前模板的库类型由预设选择:
| 预设 | 值 | 项目中的库 |
|---|---|---|
| Linux Debug / Release | ON |
动态库 |
| Windows Debug / Release | OFF |
静态库 |
Release 预设继承对应 Debug 预设中的设置。两种系统使用同一份函数声明和源文件,按照自己的预设构建即可。这里控制的是模板自己创建的库,第三方安装包仍按各自提供的方式使用。
4.buildPresets
buildPresets is a preset for the "build phase".
Build phase corresponding command:
cmake --build --preset linux-debug
Template format:
"buildPresets": [
{
"name": "linux-debug",
"configurePreset": "linux-debug"
},
{
"name": "linux-release",
"configurePreset": "linux-release"
}
]
4.1.name
"name": "linux-debug"
Build preset name.
It is generally recommended to give it the same name as the corresponding configure preset, so that the commands remain consistent:
cmake --preset linux-debug
cmake --build --preset linux-debug
4.2.configurePreset
"configurePreset": "linux-debug"
Indicates which configure preset this build preset uses to generate the build directory.
What can be filled in:
| Value | Description |
|---|---|
linux-debug |
Use Debug build directory |
linux-release |
Use Release build directory |
Must correspond to the existing configurePresets in name.
5.testPresets
当前模板还带有测试预设,例如:
{
"name": "windows-debug",
"configurePreset": "windows-debug",
"output": { "outputOnFailure": true }
}
构建完成后执行:
ctest --preset windows-debug
Linux 则使用 ctest --preset linux-debug。CTest 会运行原始 Eigen 示例,并检查输出中是否包含 Determinant = -2。后面修改 main.cpp 做语法练习时,输出变化会使这个原始示例测试失败;应该按新程序的要求修改测试,而不是把测试当作所有练习的统一运行命令。
6.继承、平台条件与其他字段
当前模板已经用到了 hidden 和 inherits 来复用配置,下面再解释它们的含义。
6.1.description
Add a longer description to the preset.
"description": "Debug build for Linux using Ninja"
6.2.hidden
Hide a certain preset and do not present it directly to the user for selection; typically used for inheritance.
"hidden": true
6.3.inherits
Inherit from another preset to reduce duplication.
{
"name": "linux-debug",
"inherits": "linux-base",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
}
6.4.${presetName}
公共预设把目录写成:
"binaryDir": "${sourceDir}/build/${presetName}"
当 windows-debug 继承公共配置时,${presetName} 会展开成 windows-debug;使用 linux-release 时则展开成 linux-release。因此不同平台、不同构建类型有自己的缓存和安装目录。
6.5.condition
例如 Windows 预设使用:
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
这里检查运行 CMake 的宿主系统。Linux 对应 Linux,Windows 对应 Windows。在 Windows 原生 CMake 中,配置列表只显示 Windows 的预设;公共 base 预设由于设置了 hidden: true,也不会单独显示。
6.6.environment
Set the environment variable.
"environment": {
"CC": "/usr/bin/gcc",
"CXX": "/usr/bin/g++"
}
本模板的 Windows 预设明确选择 gcc 和 g++,保证使用本教程的 MinGW-w64 路线,但没有写死它们的绝对路径。Linux 默认让 CMake 从系统环境选择编译器。自己的工具位置可以放进 CMakeUserPresets.json,不要把个人电脑路径提交到公共预设中。
6.7.targets
Specify which targets to build by default.
"targets": ["cmake_template"]
If not specified, all targets are built by default.
6.8.jobs
Specify the number of parallel compilations.
"jobs": 8
If not specified, it is determined by the underlying build tool.
7.Why is there no installPresets
Many people would guess that one could write:
cmake --install --preset linux-debug
However, common CMake preset files do not use this root field. This template uses a more general install command:
cmake --install build/linux-debug
The install command requires passing in the build directory, because the install rules are generated into the build directory during the configure stage.
以下图形化步骤和截图以 Linux 为例。Windows 选择 Windows GCC Debug,程序路径改为 build/windows-debug/bin/cmake_template.exe,其他操作的意义相同。
8.VSCode CMake Tools Workflow
After installing the CMake Tools extension for VSCode, it will automatically recognize CMakePresets.json。
This section maps command-line operations to the corresponding VSCode graphical interface operations.
8.1.Open the CMake panel
After opening the project root directory with VSCode, click the CMake in the left sidebar.
If CMake Tools recognizes the project correctly, you will see entries such as preset, Configure, Build, and run target.
8.2.Configure
Command line:
cmake --preset linux-debug
In the VSCode graphical interface, the corresponding setting is:
- Click Configure.
- Select
Linux Debug.

This step reads:
CMakePresets.json
CMakeLists.txt
and generate:
build/linux-debug/
If you changed CMakeLists.txt, added source files, or modified third-party dependencies, you usually need to reconfigure.
8.3.Build
Command line:
cmake --build --preset linux-debug
In the VSCode graphical interface, CMake Tools recognizes the corresponding build preset after Configure.

Then click the Build button in the lower-left corner or in the CMake panel:

This step compiles the .cpp files and generates the executable and shared libraries in the build directory.
The Debug executable file for this template is usually located at:
build/linux-debug/src/cmake_template
If you only modified the regular .cpp code, generally you just need to rebuild, not necessarily reconfigure.
8.4.Run the program in the build directory
Command line:
./build/linux-debug/src/cmake_template
In the VSCode graphical interface, the corresponding setting is:
- 选择运行/调试 target。
- 选择
cmake_template。 - 点击运行按钮。


After running, you will see the program output in the terminal.

If you want to debug with breakpoints, click the Debug button provided by CMake Tools; if you just want to run the program directly, click the Launch button.
In addition to the operation entry above, in the VSCode bottom status bar,Build next to the button, there are also Debug and Launch shortcut buttons. After selecting the cmake_template target and completing the build, you can directly click here to run or debug the program.

8.5.Install
Command line:
cmake --install build/linux-debug
In the VSCode graphical interface, you can press Ctrl+Shift+P to open the command palette, then enter:
CMake: Install

If the current selection is linux-debug preset, it is equivalent to:
cmake --install build/linux-debug
The installed program is located in:
install/linux-debug/bin/cmake_template
For everyday coding, running, and debugging, generally use the program in the build directory directly:
build/linux-debug/src/cmake_template
install is only needed when verifying the installation layout, header file installation, dynamic library RPATH, or preparing to release the program.
8.6.Summary of Correspondences
| What you want to do | Command line | VSCode CMake Tools |
|---|---|---|
| Configure the project | cmake --preset linux-debug |
Select Linux Debug and then click Configure |
| Build the project | cmake --build --preset linux-debug |
Click Build |
| Run the build output | ./build/linux-debug/src/cmake_template |
Select the cmake_template target and then click the run button |
| Debug the build output | Debug with GDB build/linux-debug/src/cmake_template |
Select the cmake_template target and then click the Debug button |
| Install the project | cmake --install build/linux-debug |
Execute in the command palette CMake: Install |
In this way, there is no need to manually write .vscode/tasks.json, and there is also no need to prepare an additional VSCode debug configuration file.
9.Operation and Debugging Notes
CMake Tools can directly run or debug the currently selected executable target, so there is no need to manually write additional run scripts.
For debugging, it is recommended to install the Microsoft C/C++ extension and GDB, because CMake Tools is responsible for selecting the target, and the actual C/C++ debugger still requires GDB/LLDB support.
If you only changed the .cpp code, generally you just need to rebuild and then run or debug.
If you modified CMakeLists.txt, added source files, or changed dependencies, it is recommended to Configure first, then Build, and then run or debug.
9.1.Why not write tasks.json
Old templates often use .vscode/tasks.json to write a long string of commands:
cmake ..
make install
source setup.bash
run app
这个模板不这样做。原因是构建、运行和调试入口都可以交给 CMake Tools 管理,命令行流程则由 CMakePresets.json 固化。
This makes responsibilities clearer:
| File | responsible for |
|---|---|
CMakePresets.json |
configure/build parameters |
| VSCode CMake Tools | Select preset, Configure, Build, run and debug target |
CMakeLists.txt |
targets, dependencies, install rules |
9.2.GDB needs to be installed
Ubuntu/Debian:
sudo apt install gdb
Fedora:
sudo dnf install gdb
10.Common Errors
10.1.Forgot to install Ninja
The error may be similar to:
CMake was unable to find a build program corresponding to "Ninja"
Solution:
sudo apt install ninja-build
Or:
sudo dnf install ninja-build
10.2.The preset name is written incorrectly
Error command:
cmake --preset debug
If there is no debug preset in the file, it will fail.
View available presets:
cmake --list-presets
10.3.No configure before build
If running directly for the first time:
cmake --build --preset linux-debug
It may fail because the build directory has not yet been generated.
Correct order:
cmake --preset linux-debug
cmake --build --preset linux-debug