JSON Compilation Database Format Specification¶
This document describes a format for specifying how to replay singlecompilations independently of the build system.
Background¶
Tools based on the C++ Abstract Syntax Tree need full information how toparse a translation unit. Usually this information is implicitlyavailable in the build system, but running tools as part of the buildsystem is not necessarily the best solution:
Build systems are inherently change driven, so running multiple toolsover the same code base without changing the code does not fit intothe architecture of many build systems.
Figuring out whether things have changed is often an IO boundprocess; this makes it hard to build low latency end user tools basedon the build system.
Build systems are inherently sequential in the build graph, forexample due to generated source code. While tools that runindependently of the build still need the generated source code toexist, running tools multiple times over unchanging source does notrequire serialization of the runs according to the build dependencygraph.
Supported Systems¶
Clang has the ability to generate compilation database fragments via-MJargument<clang-MJ\<arg>>
. You can concatenate thosefragments together between[
and]
to create a compilation database.
CurrentlyCMake (since 2.8.5) supports generationof compilation databases for Unix Makefile builds (Ninja builds in theworks) with the optionCMAKE_EXPORT_COMPILE_COMMANDS
.
For projects on Linux, there is an alternative to intercept compilercalls with a tool calledBear.
Bazel can export a compilation database viathis extractor extension.Bazel is otherwise resistant to Bear and other compiler-intercepttechniques.
Clang’s tooling interface supports reading compilation databases; seetheLibTooling documentation. libclang and itspython bindings also support this (since clang 3.2); seeCXCompilationDatabase.h.
Format¶
A compilation database is a JSON file, which consist of an array of“command objects”, where each command object specifies one way atranslation unit is compiled in the project.
Each command object contains the translation unit’s main file, theworking directory of the compile run and the actual compile command.
Example:
[{"directory":"/home/user/llvm/build","arguments":["/usr/bin/clang++","-Irelative","-DSOMEDEF=With spaces, quotes and\\-es.","-c","-o","file.o","file.cc"],"file":"file.cc"},{"directory":"/home/user/llvm/build","command":"/usr/bin/clang++ -Irelative -DSOMEDEF=\"With spaces, quotes and\\-es.\" -c -o file.o file.cc","file":"file2.cc"},...]
The contracts for each field in the command object are:
directory: The working directory of the compilation. All pathsspecified in thecommand orfile fields must be eitherabsolute or relative to this directory.
file: The main translation unit source processed by thiscompilation step. This is used by tools as the key into thecompilation database. There can be multiple command objects for thesame file, for example if the same source file is compiled withdifferent configurations.
arguments: The compile command argv as list of strings.This should run the compilation step for the translation unit
file
.arguments[0]
should be the executable name, such asclang++
.Arguments should not be escaped, but ready to pass toexecvp()
.command: The compile command as a single shell-escaped string.Arguments may be shell quoted and escaped following platform conventions,with ‘
"
’ and ‘\
’ being the only special characters. Shell expansionis not supported.Eitherarguments orcommand is required.arguments is preferred,as shell (un)escaping is a possible source of errors.
output: The name of the output created by this compilation step.This field is optional. It can be used to distinguish different processingmodes of the same input file.
Build System Integration¶
The convention is to name the file compile_commands.json and put it atthe top of the build directory. Clang tools are pointed to the top ofthe build directory to detect the file and use the compilation databaseto parse C++ code in the source tree.
Alternatives¶
For simple projects, Clang tools also recognize acompile_flags.txt
file.This should contain one argument per line. The same flags will be used tocompile any file.
Example:
-xc++-Ilibwidget/include/
Here-Ilibwidget/include
is two arguments, and so becomes two lines.Paths are relative to the directory containingcompile_flags.txt
.