Skip to content

Instantly share code, notes, and snippets.

@gtors
Created December 10, 2018 12:57
Show Gist options
  • Select an option

  • Save gtors/effe8eef7dbe7052b22a009f3c7fc434 to your computer and use it in GitHub Desktop.

Select an option

Save gtors/effe8eef7dbe7052b22a009f3c7fc434 to your computer and use it in GitHub Desktop.
Makefile -> compilation_commands.json
[Guillaume Papin(@Sarcasm)](https://github.com/sarcasm) has [a thorough article about compilation databases](https://sarcasm.github.io/notes/dev/compilation-database.html).
### [CMake](https://cmake.org/)
```zsh
% mkdir build
% (cd build; cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=YES ..)
% ln -s build/compile_commands.json
```
Caveat on Windows: CMake dumps Windows shell command line directly into `command`, depends on how ccls was built, it may confuse this field as command line from a POSIX shell, in which Windows path separator '\\' is a escape character. You can use jq to convert such entries to use `arguments` which does not have this issue:
```sh
jq '[.[] | {directory: .directory, file: .file, arguments: .command | split(" ") | map(select(length > 0)) | map(sub("\\\\\""; "\""; "g"))}]' < compile_commands.json
```
### [Build EAR](https://github.com/rizsotto/Bear)
Bear is a tool that generates a compilation database for clang tooling. It can be used for any project based on `Makefile`.
```zsh
bear make
# generates compile_commands.json
```
### [compiledb](https://github.com/nickdiego/compiledb)
### [scan-build](https://github.com/rizsotto/scan-build)
scan-build is a python package that can generate a compilation database for clang tooling (uses Bear as a backend). This too can be used for any project based on a `Makefile`.
```zsh
intercept-build make all # generates compile_commands.json from the `make all` ruleset
```
### [Ninja](https://ninja-build.org/)
```zsh
# Format: ninja -t compdb rule_names... > compile_commands.json
ninja -C out/Release -t compdb cxx cc > compile_commands.json
```
### [Waf](https://waf.io/)
Load the `clang_compilation_database` tool in your wscript:
```python
def configure(conf):
conf.load('clang_compilation_database')
```
```
./waf configure build
ln -s build/compile_commands.json
```
## [buck](https://buckbuild.com/)
```sh
buck build :helloworld#compilation-database
ln -s $(buck targets --show-output :helloworld#compilation-database | cut -d ' ' -f 2)
```
### stdout of an external command
You may use the initialization option `"compilationDatabaseCommand"` to provide the JSON compilation database. ccls will read its stdout rather than read `compile_commands.json`. This may be useful when ccls cannot parse the `compile_commands.json` correctly (e.g. MSVC cl.exe, Intel C++ Compiler options)
```sh
# extra command line option
'--init={"compilationDatabaseCommand":"mycompdb"}'
```
```elisp
(setq ccls-extra-init-params '(:compilationDatabaseCommand "mycompdb"))
```
Suppose the project is at `/tmp/c`, `mycompdb /tmp/c` will be executed with stdin=initializationOptions and the stdout should be a JSON compilation database.
You may use this shell script as a starting point:
```zsh
#!/bin/zsh
# mycompdb /tmp/c
cat >> /tmp/initialization-options
cat <<e
[ { "arguments": [ "c++", "a.o", "a.cc" ],
"directory": "/tmp/c", "file": "a.cc" } ]
e
```
An example to scrub Intel C++ Compiler options (or, even easier, check out `clang.excludeArgs` in the [Initialization options](https://github.com/MaskRay/ccls/wiki/Initialization-options)):
```zsh
#!/usr/bin/env python3
import json
import os
import sys
with open(os.path.join(sys.argv[1], 'compile_commands.json')) as f:
db = json.load(f)
for entry in db:
args = entry['arguments']
try:
# Intel C++ Compiler option that is unknown to clang
args.remove('-xHost')
except ValueError:
pass
json.dump(db, sys.stdout)
```
## Examples
### Linux kernel
```zsh
wget 'https://git.archlinux.org/svntogit/packages.git/plain/trunk/config?h=packages/linux' -O .config
yes '' | make config
bear make -j bzImage modules
```
```zsh
ccls -index ~/Dev/Linux -init='{"clang":{"excludeArgs":[
"-falign-jumps=1","-falign-loops=1","-fconserve-stack","-fmerge-constants","-fno-code-hoisting","-fno-schedule-insns","-fno-sched-pressure","-fno-var-tracking-assignments","-fsched-pressure",
"-mhard-float","-mindirect-branch-register","-mindirect-branch=thunk-inline","-mpreferred-stack-boundary=2","-mpreferred-stack-boundary=3","-mpreferred-stack-boundary=4","-mrecord-mcount","-mindirect-branch=thunk-extern","-mno-fp-ret-in-387","-mskip-rax-setup",
"--param=allow-store-data-races=0","-Wa,arch/x86/kernel/macros.s","-Wa,-"
], "extraArgs":["--gcc-toolchain=/usr"]}}'
```
### musl
```zsh
mkdir Debug; cd Debug
../configure --enable-optimize=no --enable-debug --prefix=~/.local/stow/musl
bear make -j
cd ..; ln -s Debug/compile_commands.json
```
## Misc
`compile_commands.json` should reside in the project root. Set the initialization option `compilationDatabaseDirectory` for an alternative directory containing `compile_commands.json`.
@ioperations
Copy link
Copy Markdown

linux kernel do have compile_commands.json support in master branch

@jhgorse
Copy link
Copy Markdown

jhgorse commented Jan 4, 2024

What about Makefiles for GCC toolset? compiledb option works fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment