compile_commands.json
is a file capturing the exact commands files have been compiled with, regardless of the build system. It captures the compiler, source file, include path and definitions used to build a certain source file. With this information, external tools can “rebuild” the source file as it is. It is very useful for source code tools like and clang-tidy
.
With CMake, only the generators Ninja and Makefiles will generate compile_commands.json
. Any other generator will silently ignore it.
Since the feature is controlled by an environment flag, there are 3 ways of telling CMake that is should create that file.
- Using the
environment
block inCMakePresets.json
. - Permanently alter your environment with
.bashrc
or Windows User Environment. - Invoke CMake with
-D
and orexport
/set
.
Number 1. is by far the easiest and most portable solution. The other will not be transferred to other systems automatically.
A minimal CMakePresets.json
with support for vcpkg
with automatic bootstrapping. The important bit to enable compile_commands.json
is CMAKE_EXPORT_COMPILE_COMMANDS
.
If vcpkg
is not needed, remove the linje with toolChainFile
.
{
"version": 6,
"cmakeMinimumRequired": {
"major": 3,
"minor": 25,
"patch": 0
},
"configurePresets": [
{
"name": "default",
"hidden": true,
"displayName": "Default Parent Configuration",
"binaryDir": "${sourceDir}/build-cmake/${presetName}",
"toolchainFile": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake",
"installDir": "${sourceDir}/build-cmake/${presetName}-install",
"environment": {
"CMAKE_EXPORT_COMPILE_COMMANDS": "1"
}
},
{
"name": "linux",
"inherits": "default",
"cacheVariables": {
"VCPKG_TARGET_TRIPLET": "x64-linux"
},
"generator": "Unix Makefiles",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
}
},
{
"name": "darwin",
"inherits": "default",
"cacheVariables": {
"VCPKG_TARGET_TRIPLET": "x64-linux"
},
"generator": "Unix Makefiles",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
}
}
]
}
Minimal CMakeLists.txt
:
cmake_minimum_required (VERSION 3.25.0)
project (compile_commands_example)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(compiler-cmd compiler-cmd.cpp)
Minimal C++23 source file:
#include <print>
auto main() -> int
{
std::print("foo {:d}\n\n", 42);
return 0;
}
Configure with cmake --preset linux
or cmake --preset darwin
.
Program output:
foo 42
Example output from compile_commands.json
(truncated) built on a Mac:
[
{
"directory": "/Users/kent/src/build-cmake/darwin",
"command": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -std=gnu++2b -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk -o CMakeFiles/compiler-cmd.dir/compiler-cmd.cpp.o -c /Users/kent/src/compiler-cmd.cpp",
"file": "/Users/kent/src/compiler-cmd.cpp",
"output": "CMakeFiles/compiler-cmd.dir/compiler-cmd.cpp.o"
}
]
See Also
- Left Arrow Operator
- Forward to fmt::format
- Is C++ your favorite programing language?
- NodeMCU with VSCode
- Arduino init