CMake
Generate a compilation database with CMake
CMake can generate a compilation database at configuration. When using a CMake project you have two ways of generating it:
Using the CMAKE_EXPORT_COMPILE_COMMANDS variable globally (from CMake 3.5): https://cmake.org/cmake/help/latest/variable/CMAKE_EXPORT_COMPILE_COMMANDS.html
Using the EXPORT_COMPILE_COMMANDS target property for the specific target you want to analyze (from CMake 3.20): https://cmake.org/cmake/help/latest/prop_tgt/EXPORT_COMPILE_COMMANDS.html#prop_tgt:EXPORT_COMPILE_COMMANDS
Compilation database generation with CMake is only available with Makefiles and Ninja generators. Any other generator will ignore these variables and the compilation database will not be generated.
If your CMake configuration has multiple targets, it is strongly recommended to activate compile commands generation only for the target you want to analyze. Generating compile commands globally in multi-target projects may lead to undefined behaviour if some sources are compiled multiple times with different commands.
When running CMake, compile_commands.json is generated in the build directory. For example, running:
cmake -B build -DCMAKE_BUILD_TYPE=Release .will produce ./build/compile_commands.json.
In beLow, enter the CMake command as the "Configure script" when asked; beLow will find the compile_commands.json file by name.
Try not to leave any stale compile_commands.json files in your project root if you can generate them at configuration or build time. A leftover file may be used in priority and cause issues if it is out of date or uses absolute paths (in copy mode).
Windows specificities
On Windows, CMake's compile-commands generation can produce commands with unexpected escaping of backslashes and quotes. A common problematic case is when injecting include file names via preprocessor definitions.
Example C/C++ usage you might try:
#include LIB_HEADER_FILEAnd in CMakeLists.txt:
add_definitions(-DLIB_HEADER_FILE="lib.h")CMake may generate an over-escaped entry in compile_commands.json like -DLIB_HEADER_FILE=\"lib.h\", which breaks the intended injection.
There are two ways to address this:
Modify the compilation database after generation with a script (not recommended).
Prefer rewriting the macro so the compiler adds the quotes. This is the recommended approach.
Recommended fix in source:
#define INCLUDE_FILE(x) #x
#include INCLUDE_FILE(LIB_HEADER_FILE)Then, in your CMakeLists.txt, define the macro without quotes:
add_definitions(-DLIB_HEADER_FILE=lib.h)or for a target:
target_compile_definitions(<your-target> PUBLIC LIB_HEADER_FILE=lib.h)With this approach, after running CMake configuration the generated compilation database will be correct.
Last updated 1 month ago
