VS Code + CMake Tools
Visual Studio Code with the CMake Tools extension provides a lightweight yet powerful CMake development environment. It supports configure, build, debug, test, and preset workflows directly from the editor.
CMakePresets.json natively since version 1.11. If your project has presets, the extension will automatically offer them in the configuration workflow — no settings.json hacking required.
Installing the Extension
# Install from the command line
code --install-extension ms-vscode.cmake-tools
code --install-extension ms-vscode.cpptools
# Or search "CMake Tools" in the Extensions panel (Ctrl+Shift+X)
Configure / Build / Debug Workflow
Once installed, the status bar shows CMake controls. The typical workflow:
# 1. Open folder containing CMakeLists.txt
# → Extension auto-detects and prompts to configure
# 2. Select a kit (compiler) — Ctrl+Shift+P → "CMake: Select a Kit"
# → Scans for GCC, Clang, MSVC installations
# 3. Select a configure preset (if CMakePresets.json exists)
# → Ctrl+Shift+P → "CMake: Select Configure Preset"
# 4. Configure the project — Ctrl+Shift+P → "CMake: Configure"
# → Runs cmake -S . -B build/
# 5. Build — Ctrl+Shift+P → "CMake: Build" (or F7)
# → Runs cmake --build build/
# 6. Debug — Ctrl+Shift+P → "CMake: Debug" (or Ctrl+F5)
# → Launches debugger attached to selected target
Useful .vscode/settings.json for CMake projects:
# .vscode/settings.json
{
"cmake.buildDirectory": "${workspaceFolder}/build/${buildType}",
"cmake.configureOnOpen": true,
"cmake.generator": "Ninja",
"cmake.parallelJobs": 0,
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools"
}
flowchart TD
OPEN[Open Folder] --> DETECT[Extension Detects
CMakeLists.txt]
DETECT --> KIT{CMakePresets.json
exists?}
KIT -->|Yes| PRESET[Select Configure Preset]
KIT -->|No| SELECTKIT[Select Kit
GCC/Clang/MSVC]
PRESET --> CONFIGURE[Configure
cmake -S . -B build]
SELECTKIT --> CONFIGURE
CONFIGURE --> BUILD[Build
cmake --build build]
BUILD --> RUN[Run / Debug
Launch target]
BUILD --> TEST[Test
ctest --test-dir build]
CLion
JetBrains CLion has native CMake support — it uses CMake as its project model directly, with no intermediate configuration files. This makes it one of the most seamless CMake IDEs available.
Toolchain Configuration
# CLion auto-detects toolchains, but you can configure:
# Settings → Build, Execution, Deployment → Toolchains
# For remote development:
# 1. Add Remote Host toolchain (SSH credentials)
# 2. CLion syncs sources, builds remotely, returns results
# 3. Debug runs remotely via gdbserver/lldb-server
# CMake profiles in CLion (Settings → CMake):
# - Profile name, build type, generator
# - CMake options: -DCMAKE_PREFIX_PATH=/opt/libs
# - Build directory: cmake-build-debug, cmake-build-release
CLion supports CMakePresets.json since version 2021.2. When a presets file exists, CLion offers preset-based profiles instead of manual configuration.
Try It: Full VS Code CMake Workflow
Install the CMake Tools and C/C++ extensions. Open a CMake project folder, select Ninja as the generator, choose your compiler kit, and configure. Set a breakpoint in main(), then use "CMake: Debug" to hit the breakpoint. Observe the variables panel and step through your code.
Visual Studio
Visual Studio 2019+ supports CMake natively via Open Folder mode — no need to generate .sln files. It reads CMakeLists.txt directly and provides IntelliSense, build, and debug integration.
CMakePresets.json Support (Modern)
# Visual Studio 2022 17.0+ uses CMakePresets.json natively
# File → Open → Folder (select folder with CMakeLists.txt)
# VS reads CMakePresets.json and populates the configuration dropdown
# Legacy: CMakeSettings.json (VS-specific, avoid for new projects)
# Modern: CMakePresets.json (cross-IDE, team-shareable)
# Example CMakePresets.json for Visual Studio
{
"version": 6,
"configurePresets": [
{
"name": "msvc-debug",
"displayName": "MSVC Debug",
"generator": "Visual Studio 17 2022",
"binaryDir": "${sourceDir}/build/${presetName}",
"architecture": { "value": "x64", "strategy": "set" },
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install"
}
},
{
"name": "msvc-release",
"displayName": "MSVC Release",
"inherits": "msvc-debug",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
}
]
}
Qt Creator
Qt Creator imports CMake projects directly and provides full IDE features including code model, debugging, and deployment configuration:
# Open CMake project in Qt Creator:
# File → Open File or Project → select CMakeLists.txt
# Kit configuration:
# Tools → Options → Kits → Add
# - Compiler: Select GCC/Clang/MSVC
# - CMake: Path to cmake executable
# - Qt version: (optional, for Qt projects)
# Qt Creator generates a .qtc_clangd/ directory for code model
# It respects CMakePresets.json when available
Xcode Generator
On macOS, you can generate Xcode projects from CMake for native debugging and profiling:
# Generate Xcode project
cmake -S . -B build-xcode -G Xcode
# Open in Xcode
open build-xcode/MyProject.xcodeproj
# Build from command line using xcodebuild
cmake --build build-xcode --config Debug
# Xcode-specific: set the default scheme
# Product → Scheme → Manage Schemes → set your executable target
# Note: Xcode is a multi-config generator
# CMAKE_BUILD_TYPE is ignored; use --config at build time
CMake File API
The CMake File API is the protocol IDEs use to query project metadata. It replaces the deprecated server mode and provides structured JSON output.
compile_commands.json
The most important IDE integration file — enables IntelliSense, clangd, and static analysis tools:
# Enable in CMakeLists.txt (recommended in top-level)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Or pass on command line
cmake -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
# Or set in CMakePresets.json
{
"cacheVariables": {
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
}
}
# The generated file: build/compile_commands.json
[
{
"directory": "/home/user/project/build",
"command": "/usr/bin/g++ -std=c++20 -I/home/user/project/include -o CMakeFiles/mylib.dir/src/engine.cpp.o -c /home/user/project/src/engine.cpp",
"file": "/home/user/project/src/engine.cpp"
}
]
# Symlink to project root for tools that expect it there
ln -s build/compile_commands.json .
# Configure clangd to find it: .clangd file
# CompileFlags:
# CompilationDatabase: build/
compile_commands.json is only generated for Makefile and Ninja generators. Multi-config generators (Visual Studio, Xcode) do not produce this file. For those, use the CMake File API or IDE-native IntelliSense providers.
Debugging CMake
When your CMake configuration behaves unexpectedly, these diagnostic tools help trace the problem:
Trace Mode
# Full trace — prints every command CMake executes
cmake -S . -B build --trace
# Trace with source file and line numbers (verbose)
cmake -S . -B build --trace-expand
# Trace only specific files (much less noise)
cmake -S . -B build --trace-source=CMakeLists.txt
# Redirect trace to a file for analysis
cmake -S . -B build --trace-redirect=trace.log
Debug Find Operations
# Debug find_package, find_library, find_path issues
cmake -S . -B build --debug-find
# Show detailed output about the configuration process
cmake -S . -B build --debug-output
# Increase log verbosity
cmake -S . -B build --log-level=DEBUG
# Available log levels: ERROR, WARNING, NOTICE, STATUS, VERBOSE, DEBUG, TRACE
Try It: Trace a Missing Package
Add find_package(NonExistentLib REQUIRED) to a test project. Run cmake --debug-find to observe the search paths CMake checks. Then use --trace-source=CMakeLists.txt to see the exact line where failure occurs. Finally, fix it by providing -DCMAKE_PREFIX_PATH=/correct/path.
CMakePresets.json for IDEs
CMakePresets.json is the universal configuration mechanism that works across all major IDEs. It replaces IDE-specific configuration files with a single, version-controlled preset file.
# CMakePresets.json — shared across the team (committed to VCS)
{
"version": 6,
"cmakeMinimumRequired": { "major": 3, "minor": 21, "patch": 0 },
"configurePresets": [
{
"name": "default",
"hidden": true,
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
}
},
{
"name": "dev-ninja",
"displayName": "Development (Ninja)",
"inherits": "default",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_CXX_COMPILER": "g++"
}
},
{
"name": "ci-release",
"displayName": "CI Release Build",
"inherits": "default",
"generator": "Ninja",
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
}
],
"buildPresets": [
{ "name": "dev-build", "configurePreset": "dev-ninja" },
{ "name": "ci-build", "configurePreset": "ci-release", "jobs": 4 }
],
"testPresets": [
{ "name": "dev-test", "configurePreset": "dev-ninja", "output": { "outputOnFailure": true } }
]
}
# CMakeUserPresets.json — developer-specific overrides (git-ignored)
{
"version": 6,
"configurePresets": [
{
"name": "my-local",
"inherits": "dev-ninja",
"cacheVariables": {
"CMAKE_PREFIX_PATH": "/opt/custom-libs"
}
}
]
}
flowchart TD
PRESETS[CMakePresets.json
Version controlled] --> VSCODE[VS Code
CMake Tools]
PRESETS --> CLION[CLion
CMake Profiles]
PRESETS --> VS[Visual Studio
Open Folder]
PRESETS --> QTC[Qt Creator
Kit Selection]
PRESETS --> CLI[Command Line
cmake --preset]
VSCODE --> FILEAPI[CMake File API
build/.cmake/api/]
CLION --> FILEAPI
VS --> FILEAPI
FILEAPI --> CC[compile_commands.json]
FILEAPI --> TARGETS[Target metadata]
FILEAPI --> CACHE[Cache entries]
Recommended IDE Workflows
Each IDE has strengths. Here are recommended workflows based on use case:
| IDE | Best For | Key Advantage | Preset Support |
|---|---|---|---|
| VS Code | Lightweight, remote, polyglot | Extensible, fast startup | Native (v1.11+) |
| CLion | Full-time C++ development | Deep refactoring, analysis | Native (2021.2+) |
| Visual Studio | Windows/MSVC targeting | Best Windows debugger | Native (VS 2022+) |
| Qt Creator | Qt/embedded projects | Qt-specific tooling | Native (7.0+) |
| Xcode | macOS/iOS targeting | Instruments profiling | Via generator |
Try It: One Preset, Three IDEs
Create a CMakePresets.json with a Ninja-based debug preset. Open the same project in VS Code, CLion (or Visual Studio), and from the command line (cmake --preset dev-ninja). Verify all three produce identical build output. Then create a CMakeUserPresets.json with local overrides and confirm it's only picked up on your machine.
CMakePresets.json to version control and add CMakeUserPresets.json to .gitignore. This gives the team a shared baseline while letting individuals customize paths, generators, and debug settings locally.