A tiny Swift CLI tool to generate a compile_commands.json
database for Xcode projects and workspaces, enabling powerful C/C++/Objective-C code navigation and completion with tools like clangd.
gen_cdb.swift
is a single-file Swift script that wraps xcodebuild
, watches the build log for Clang compile invocations, and writes a compile_commands.json
file in your current directory. This file is the standard way to provide build information to C/C++/Objective-C language tools, such as clangd, for features like code completion, go-to-definition, and more.
- No dependencies: Just needs Swift and Xcode.
- Works with both
.xcodeproj
and.xcworkspace
projects. - Forwards all arguments to
xcodebuild
—use it just like you would usexcodebuild
.
Xcode does not natively generate compile_commands.json
, but many modern C/C++/Objective-C tools (like clangd, ccls, etc.) rely on it for accurate code intelligence. This script makes it easy to generate the file for any Xcode-based project.
No installation required! Just download or copy gen_cdb.swift
into your project root and make it executable:
chmod +x gen_cdb.swift
You need Swift (comes with Xcode) and Xcode command line tools installed.
Run the script from your project root, passing your usual xcodebuild
arguments. For example:
./gen_cdb.swift -workspace MyApp.xcworkspace -scheme MyApp -configuration Debug clean build COMPILER_INDEX_STORE_ENABLE=NO
./gen_cdb.swift -project MyLib.xcodeproj -scheme MyLib build
- All arguments after the script name are forwarded directly to
xcodebuild
. - When the build finishes, a
compile_commands.json
file will be created in your current directory.
Add this to your .vscode/settings.json
:
{
"clangd.arguments": [
"--compile-commands-dir=${workspaceFolder}"
]
}
- Runs
xcodebuild
with your arguments. - Watches the build log for Clang compile invocations.
- Tracks directory changes (
cd ...
) to record the correct working directory for each command. - Writes a
compile_commands.json
file compatible with clangd and other tools.
- If you see
warning: no compile commands captured – did the build succeed?
, check your build arguments and ensure your scheme is building C/C++/Objective-C targets. - The script only captures Clang invocations (not Swift or other compilers).
This is mostly a LLM generated hack that turned out to be good enough for my usecases. I put it on github to not lose track of it and because it might also be good enough for others. I'm not really looking to spend a lot of time maintaining this and reviewing large PRs. Feel free to fork and maybe let me know if you turn this into a super awesome, generic solution ;-)