generate-compile-commands

Installation
SKILL.md

Generate compile_commands.json

The C++ language server needs a compile_commands.json (clang compilation database) to understand a project. How you produce one depends on the build system: CMake can export it directly, MSBuild needs an external extractor.

Always regenerate compile_commands.json when this skill runs, even if one already exists for the project. For MSBuild, write it to .mscppls\compile_commands.json at the workspace root (the examples below do this); mscppls auto-discovers any compile_commands.json within the workspace, so no cpp-lsp.json is required. Add .mscppls/ to .gitignore so it does not get committed. mscppls hot-reloads the file content; /restart is only needed after changing the plugin's lsp.json or the workspace cpp-lsp.json (those are read once at LSP startup).

Do not mix build systems in one database. Which build system applies is a selection decision, not a guess: work through Selecting the build system below before running anything, then follow the matching section exactly.

Selecting the build system (do this first)

Choose the build system before producing anything, in precedence order: (1) explicit user intent (asked for CMake or the MSBuild extractor); (2) committed configuration (a committed msbuild-extractor.json declares MSBuild; a committed CMake preset or established configure declares CMake); (3) workspace context (a .sln/.slnx/.vcxproj selected as the workspace or target is MSBuild); (4) the repo's build docs.

Hard rule (narrow trigger). Run the MSBuild extractor and reject a CMake- or Ninja-produced compile_commands.json only when (a) a committed msbuild-extractor.json is present, or (b) the task is explicitly MSBuild, or (c) a specific .sln/.slnx/.vcxproj is the selected workspace or target. Then use the extractor even if a CMakeLists.txt also exists; the finish check rejects a CMake-written database. The trigger is the selection decision, not mere presence: an incidental or stale .sln/.slnx/.vcxproj with none of (a)/(b)/(c) holding does not make the task MSBuild and does not reject CMake.

Inverse guard. If user intent or committed configuration selects CMake, CMake wins even when a solution file exists, and a CMake-only repo (no committed solution, no .vcxproj, no msbuild-extractor.json) uses the CMake export path. This rule never forbids CMake outright. Tie-break: if both a committed CMake config (CMakePresets.json, CMakeSettings.json) and a committed msbuild-extractor.json exist, explicit user CMake intent still wins; absent explicit CMake intent, the committed msbuild-extractor.json makes this an MSBuild extractor task.

CMake projects

CMake writes compile_commands.json itself; no external extractor needed. Enable it at configure time (or persist it with set(CMAKE_EXPORT_COMPILE_COMMANDS ON) in CMakeLists.txt):

Installs
1
GitHub Stars
55
First Seen
Oct 12, 2026