Guillaume Papin(@Sarcasm) has a thorough article about compilation databases.
% 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:
jq '[.[] | {directory: .directory, file: .file, arguments: .command | split(" ") | map(select(length > 0)) | map(sub("\\\\\""; "\""; "g"))}]' < compile_commands.json
Bear is a tool that generates a compilation database for clang tooling. It can be used for any project based on Makefile
.
bear make
# generates compile_commands.json
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
.
intercept-build make all # generates compile_commands.json from the `make all` ruleset
# Format: ninja -t compdb rule_names... > compile_commands.json
ninja -C out/Release -t compdb cxx cc > compile_commands.json
Load the clang_compilation_database
tool in your wscript:
def configure(conf):
conf.load('clang_compilation_database')
./waf configure build
ln -s build/compile_commands.json
buck build :helloworld#compilation-database
ln -s $(buck targets --show-output :helloworld#compilation-database | cut -d ' ' -f 2)
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)
# extra command line option
'--init={"compilationDatabaseCommand":"mycompdb"}'
(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:
#!/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):
#!/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)
wget 'https://git.archlinux.org/svntogit/packages.git/plain/trunk/config?h=packages/linux' -O .config
yes '' | make config
bear make -j bzImage modules
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"]}}'
mkdir Debug; cd Debug
../configure --enable-optimize=no --enable-debug --prefix=~/.local/stow/musl
bear make -j
cd ..; ln -s Debug/compile_commands.json
compile_commands.json
should reside in the project root. Set the initialization option compilationDatabaseDirectory
for an alternative directory containing compile_commands.json
.