CMakePresets and Build Installation
CMakePresets.json is used to save common CMake configurations. It solves the problem of having to manually write long series of cmake -S ... -B ... -G ... -D... commands every time.
The CMakePresets.json of this template is as follows:
{
"version": 6,
"cmakeMinimumRequired": {
"major": 3,
"minor": 25,
"patch": 0
},
"configurePresets": [
{
"name": "linux-debug",
"displayName": "Linux Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/linux-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/linux-debug"
}
},
{
"name": "linux-release",
"displayName": "Linux Release",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/linux-release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/linux-release"
}
}
],
"buildPresets": [
{
"name": "linux-debug",
"configurePreset": "linux-debug"
},
{
"name": "linux-release",
"configurePreset": "linux-release"
}
]
}
root field
version
"version": 6
Indicates the CMakePresets.json file format version, not the project version.
What can be filled in:
| value | Meaning |
|---|---|
1、2、3、... | CMake preset file format version |
6 | The version used in this template is designed for CMake 3.25 and above. |
Note:
- This is not the version number of
cmake_template. - If you want to maintain compatibility with older CMake, you may need to lower the
version, but some fields may no longer be usable. - If your local CMake is very new, you don't necessarily need to use the highest preset version; just enough is fine.
cmakeMinimumRequired
"cmakeMinimumRequired": {
"major": 3,
"minor": 25,
"patch": 0
}
Indicates the minimum CMake version required to read this preset file.
What can be filled in:
|field|Here is the translation of the provided Simplified Chinese Markdown fragment into natural American English, following all specified rules.
Example|Meaning|
|:---|:---|:---|
|major|3|Major Version Number|
|minor|25|Minor version number|
|patch|0|patch version number|
This template requires CMake >= 3.25, because the top-level CMakeLists.txt also specifies:
cmake_minimum_required(VERSION 3.25)
It's best to keep them consistent.
configurePresets
configurePresets is a preset for the configuration phase.
Corresponding commands for the configuration phase:
cmake --preset linux-debug
It is equivalent to telling CMake:
- Which generator to use?
- Where is the build directory located?
- What is the build type.
- Where is the installation directory?
- Should
compile_commands.jsonbe generated?
name
"name": "linux-debug"
machine-readable name of a preset.
What can be filled in:
| writing method | Explanation |
|---|---|
linux-debug | This template's Debug preset |
linux-release | Release preset for this template |
debug | That works too, but it's not as clear as linux-debug. |
gcc-debug | If you want to differentiate compilers, here’s how you can name them: |
- By platform: GCC, Clang, MSVC (Microsoft Visual C++)
- By language: GCC (GNU Compiler Collection), Swift (for Swift), Javac (for Java)
- By function or origin: LLVM, Go compiler (gc), Rustc (for Rust)
- By version or variant: GCC 9, Clang 11, MSVC 2019|
|
clang-debug|If we add a Clang preset, we could name it like this.|
Requirements:
- You can't have duplicates in the same array.
- The names in
buildPresetsshould reference the names here. - This is the name used by the command line.
Example:
cmake --preset linux-debug
displayName
"displayName": "Linux Debug"
A human-readable name, primarily used for IDE display, such as the preset list in VSCode CMake Tools.
What can be filled in:
| writing method | Explanation |
|---|---|
Linux Debug | Clear |
Linux Release | Clear |
Debug | Okay, but without platform distinction |
Fedora GCC Debug | If there are many presets, you can be more specific. |
This field does not affect the actual build logic.
generator
"generator": "Ninja"
Specify what build system files CMake should generate.
Common Selectable Values for Linux:
| value | Explanation |
|---|---|
Ninja | Recommended, fast, clean output, and well-suited for VSCode CMake Tools. |
Unix Makefiles | Traditional Makefile workflow |
Ninja Multi-Config | Configure Ninja for multiple configurations, allowing simultaneous management of Debug and Release builds. |
This template only supports Linux and uses Ninja, so it is hardcoded as follows:
"generator": "Ninja"
If using Unix Makefiles, the build command still works:
cmake --build --preset linux-debug
But the underlying layer is not Ninja.
binaryDir
"binaryDir": "${sourceDir}/build/linux-debug"
Specify the build directory.
What can be filled in:
| writing method | Explanation |
|---|---|
${sourceDir}/build/linux-debug | Recommend, keeping build artifacts in the project's build subdirectory. |
${sourceDir}/build/debug | That works too, but it's not as clear as linux-debug. |
/tmp/my-build | It can be placed outside the project, but it is not suitable as a template default value. |
Common Macros:
| macro | Meaning |
|---|---|
${sourceDir} | Project source code root directory |
${presetName} | Current preset name |
${sourceParentDir} | the parent directory of the root source directory |
It can also be written as:
"binaryDir": "${sourceDir}/build/${presetName}"
This way, linux-debug will be automatically generated to:
build/linux-debug
This template explicitly outlines the table of contents to make it more intuitive when starting out.
cacheVariables
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/linux-debug"
}
cacheVariables is equivalent to the -D parameter in the command line.
For example:
"CMAKE_BUILD_TYPE": "Debug"
Equivalent to:
-DCMAKE_BUILD_TYPE=Debug
Frequently used cache variables
CMAKE_BUILD_TYPE
"CMAKE_BUILD_TYPE": "Debug"
Build types used in mono-configuration generators. Both Ninja and Unix Makefiles are common mono-configuration generators.
What can be filled in:
| value | effect |
|---|---|
Debug | Debug builds, typically with -g, minimal optimization |
Release | Release builds are typically done with optimization enabled. |
RelWithDebInfo | Optimization + Debug Information |
MinSizeRel | optimize volume |
Common choices:
| Scene | Recommendation |
|---|---|
| Write code, debug breakpoints. | Debug |
| Release, Performance Test | Release |
| Performance testing but still want to retain symbols. | RelWithDebInfo |
| Embedded or size-sensitive | MinSizeRel |
CMAKE_EXPORT_COMPILE_COMMANDS
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
Should compile_commands.json be generated?
What can be filled in:
| value | effect |
|---|---|
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.
Recommend fixed enable in template:
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
Make clangd find compile_commands.json
merely generating compile_commands.json does not necessarily mean clangd can automatically find it.
Before using this method in VSCode, you need to install the official LLVM clangd extension. CMake Tools is responsible for configuring, building, and selecting targets, while clangd handles code completion, Jump-to-definition and semantic checks, among other editing features, are not part of the same extension.
This template sets the Debug build directory to:
build/linux-debug/
Therefore, execute:
It looks like your message is incomplete or unclear. Could you please provide more details or specify what you'd like me to help you with?
cmake --preset linux-debug
Afterwards, the compilation database is located at:
build/linux-debug/compile_commands.json
Clangd will by default traverse upward from the directory where the source file is located.
It usually can locate the project root directory or the build/ direct parent directory.
databases, but might not continue searching for multi-layered ones like build/linux-debug/.
preset directory.
If clangd doesn't find a database, it enters fallback mode, using only a small number of default settings. Parameter analysis source files. At this point, even if CMake compiles without issues, the following message may still appear in VSCode:
- Project header file not found.
- Eigen、OpenCV 等第三方库显示找不到。
- C++ standard recognition errors, such as a project using C++23 while clangd analyzes it according to C++17.
- The jump-to-definition, auto-completion, and error suggestions are inaccurate.
It is recommended to create .clangd at the project root directory:
CompileFlags:
CompilationDatabase: build/linux-debug
The directory structure will become:
.
├── .clangd
├── CMakeLists.txt
├── CMakePresets.json
├── build/
│ └── linux-debug/
│ └── compile_commands.json
└── src/
CompilationDatabase uses a path relative to the directory where .clangd is located, so do not
Write the absolute path to a specific file on the user's computer. This file stores only generic project configurations and can be committed to
Git。
Note that .clangd does not generate a compilation database. This applies when using the project for the first time or when modifications have been made.
After setting up the environment, configuring compilation options, dependencies, and presets, it is still necessary to re-execute:
cmake --preset linux-debug
or in VSCode CMake Tools select linux-debug and click Configure.
If .clangd is created but not immediately effective, you can execute in the VSCode command palette:
clangd: Restart language server
You can also close and reopen the current .cpp file.
If you have the Microsoft C/C++ extension installed alongside the editor's built-in tools and are seeing two sets of duplicate errors, this is usually caused by conflicting IntelliSense or linting features. The editor’s default language service and the extension’s service are both analyzing the code simultaneously. To resolve this, you can disable the editor’s native IntelliSense or set the Microsoft extension to take priority. Check your settings (e.g., in VS Code, adjust "C_Cpp.intelliSenseEngine" and "editor.suggest.selection") to ensure only one tool is active. If the issue persists, look for other conflicting C/C++ related extensions. You can retain the GDB debugging functionality provided by this extension while turning off its IntelliSense. Let clangd be solely responsible for code analysis. This is a personal VSCode setting and does not need to be written into CMake. Template.
Check if clangd is actually working
Open in VSCode:
查看 -> 输出 -> clangd
Under normal circumstances, you should see similar content:
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
Explanation: clangd is still not reading the compilation database. Check the following in order:
- Check if the file explorer panel in VSCode shows your project's top-level files and folders. Alternatively, open a terminal within VSCode; the default path should be your project root.
.clangdis located in the project root directory.- Has
cmake --preset linux-debugbeen executed? build/linux-debug/compile_commands.jsonis real or exists.- Check if the directory name in
.clangdis exactly the same as inbinaryDir.
If you can directly use clangd in the system terminal, you can also check individual source files:
clangd --check=src/main.cpp
The output should display that it has loaded build/linux-debug/compile_commands.json.
and use the include paths, macro definitions, and C++ standards generated by CMake as well.
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 first generate the corresponding database:
cmake --preset linux-release
Daily development typically uses build/linux-debug. Avoid having .clangd point to
A build directory that has not yet been generated or has already expired.
CMAKE_INSTALL_PREFIX
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/linux-debug"
Specify the installation directory.
What can be filled in:
| writing method | Explanation |
|---|---|
${sourceDir}/install/linux-debug | This template Debug installation directory |
${sourceDir}/install/linux-release | The installation directory for this template's release version |
/usr/local | System-level installation path requires permissions and is unsuitable as a template default. |
/opt/my_project | system-level or deployment path |
This template places the installation directory inside the project for easier learning and removal.
After installation, run:
./install/linux-debug/bin/cmake_template
buildPresets
buildPresets is the preset for the build stage.
Build phase corresponding command:
cmake --build --preset linux-debug
Template format:
"buildPresets": [
{
"name": "linux-debug",
"configurePreset": "linux-debug"
},
{
"name": "linux-release",
"configurePreset": "linux-release"
}
]
name
"name": "linux-debug"
Construct the preset name.
一般建议使用与对应配置预设同名的命令,这样操作起来会更一致。
cmake --preset linux-debug
cmake --build --preset linux-debug
configurePreset
"configurePreset": "linux-debug"
This specifies which configure preset the build preset uses to generate the build directory.
What can be filled in:
| value | Explanation |
|---|---|
linux-debug | Use Debug build directory |
linux-release | Use the Release build directory |
Must correspond to the existing name within configurePresets.
Common extensible fields
When you're starting out, you might not need this right away, but you could come across it later.
description
Add longer descriptions to presets.
"description": "Debug build for Linux using Ninja"
hidden
Hide a certain preset from direct user selection, typically used for inheritance.
"hidden": true
inherits
Inherit from another preset to reduce repetition.
{
"name": "linux-debug",
"inherits": "linux-base",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
}
environment
Set environment variables.
"environment": {
"CC": "/usr/bin/gcc",
"CXX": "/usr/bin/g++"
}
Generally, it's not advisable to hardcode the compiler in the default template unless your project specifically requires a particular toolchain.
targets
Specify which targets to build by default.
"targets": ["cmake_template"]
If not specified, all targets will be built by default.
jobs
Specify the number of parallel compilations.
"jobs": 8
When not specified, it is determined by the underlying build tools.
Why isn't there installPresets?
Many people would guess that you could write:
cmake --install --preset linux-debug
Yes, that's correct. Typical CMake preset files do not use the root field. This template adopts a more general installation command.
cmake --install build/linux-debug
The installation command needs to be passed the build directory, as the installation rules are generated during the configuration step into the build directory.
VSCode CMake Tools Workflow
After installing the CMake Tools extension for VSCode, it will automatically recognize CMakePresets.json.
In this section, we map command-line operations to their corresponding actions in the VSCode graphical interface.
Open the CMake panel.
After opening the project root directory in VSCode, click the CMake icon on the left sidebar.
If CMake Tools properly identifies the project, you will see entries for preset, Configure, Build, run target, and others.
Configure
Command line:
cmake --preset linux-debug
In the VSCode graphical interface, what corresponds is:
- Click Configure.
- Choose
Linux Debug.

This step will read:
CMakePresets.json
CMakeLists.txt
and generate:
build/linux-debug/
If you modify CMakeLists.txt, add new source files, or change third-party dependencies, you typically need to re-run Configure.
Build
Command line:
cmake --build --preset linux-debug
In the graphical interface of VSCode, CMake Tools will recognize the corresponding build presets after configuration.

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

This step will compile the .cpp file and generate the executable and dynamic library files in the build directory.
The Debug executable for this template is typically found at:
build/linux-debug/src/cmake_template
If you've only modified ordinary .cpp code, you generally just need to rebuild, not necessarily reconfigure.
Run the program in the build directory.
Command line:
./build/linux-debug/src/cmake_template
In the VSCode graphical interface, what corresponds is:
- Select the run/debug target.
- Choose
cmake_template. - Click the run button.


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, click the Launch button.
In addition to the access points mentioned above, the VSCode bottom status bar also has Debug and Launch quick buttons next to the Build button. Once you've selected a cmake_template target and completed the build, you can directly click here to run or debug your program.

Install
Command line:
cmake --install build/linux-debug
In the VSCode GUI, you can press Ctrl+Shift+P to open the command panel, then input:
CMake: Install

If the currently selected linux-debug preset is active, it is equivalent to:
cmake --install build/linux-debug
The installed program is located at: I18N_PROTECTED_0
install/linux-debug/bin/cmake_template
For daily coding, running, and debugging, you typically directly use the programs in the build directory.
build/linux-debug/src/cmake_template
You only need to run the install command when verifying the installation layout, installing header files, setting up dynamic library RPATHs, or preparing the program for release.
Mapping Summary
| What you want to do | command line | VSCode CMake Tools |
|---|---|---|
| Configure the project | cmake --preset linux-debug | After selecting Linux Debug, click Configure. |
| Compile project | cmake --build --preset linux-debug | Click Build |
| Run build artifacts | ./build/linux-debug/src/cmake_template | After selecting the cmake_template target, click the run button. |
| Debugging build artifacts | Debugging with GDB build/linux-debug/src/cmake_template | After selecting the cmake_template target, click the Debug button. |
| installation project | cmake --install build/linux-debug | Execute command panel CMake: Install |
This way, you don't need to manually write .vscode/tasks.json, nor do you need to prepare an extra VSCode debugging configuration file.
Running and Debugging Considerations
CMake Tools can directly run or debug the currently selected executable target, so there's no need to write additional run scripts manually.
If you need to debug, it's recommended to install the Microsoft C/C++ extension and GDB, since CMake Tools handles target selection, but the actual C/C++ debugger still requires GDB/LLDB support.
If you've only changed the .cpp code, simply rebuilding and then running or debugging should suffice.
If you have changed CMakeLists.txt, added new source files, or modified dependencies, it is recommended to first Configure, then Build, and afterward Run or Debug.
Why not write tasks.json
The old template commonly uses .vscode/tasks.json for long command strings:
cmake ..
make install
source setup.bash
run app
This template doesn't work that way. The reason is that the build, run, and debug entry points can be handled by CMake Tools, while the command-line workflow is governed by 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 | target, dependency, installation rules |
Need to install gdb
Ubuntu/Debian:
sudo apt install gdb
Fedora:
sudo dnf install gdb
Common Errors
Forgot to install Ninja.
The error message might 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
preset name is misspelled
Error command:
cmake --preset debug
If the file doesn't have the debug preset, it will fail.
View available presets:
cmake --list-presets
I forgot to configure before building.
If you just run it for the first time:
cmake --build --preset linux-debug
It might fail because the build directory hasn't been created yet.
Correct order:
cmake --preset linux-debug
cmake --build --preset linux-debug