I have found a way to generate a JSON compilation database from an Xcode project without relying on external tools.
Tools that rely on processing xcodebuild
output are all deprecated (oclint-xcodebuild, xctool) or buggy at best (xcpretty), as output format is an implementation detail and subject to change.
The following approach was tested with Xcode 13.4.1 on macOS 12 Monterey and Apple Silicon M1 Pro.
In Xcode Build Settings the following compiler flag can be set:
OTHER_CFLAGS = $(inherited) -gen-cdb-fragment-path $(PROJECT_DIR)/CompilationDatabase
Alternatively, the flag can be passed when invoking xcodebuild
:
xcrun xcodebuid clean build -project TestProject.xcodeproj -target TestTarget -configuration Debug OTHER_CFLAGS="\$(inherited) -gen-cdb-fragment-path \$(PROJECT_DIR)/CompilationDatabase"
This instructs clang to emit a fragment of the compilation database for each compilation. These fragments can easily be combined into the final compilation database by using the following command:
sed -e '1s/^/[\'$'\n''/' -e '$s/,$/\'$'\n'']/' *.json > compile_commands.json
Of course it's recommended to validate fragments, but that cannot be done without external tools.
For full details regarding compiler flags, validation of fragments, and references, check out the gist:
Generate a JSON Compilation Database from an Xcode project