Introduction
A compilation database is a JSON file (compile_commands.json is the default name), which consists of an array of command objects. Each command object consists of:
- A compilation database is a JSON file (compile_commands.json is the default name), which consists of an array of command objects. Each command object consists of:
- Directory: The working directory of the compilation. All paths specified in the command or file fields must be either absolute or relative to this directory.
- File: Source file to be compiled.
- Command: The compile command executed.
- Example:
![](https://docs.embold.io/wp-content/uploads/2019/12/c1.png)
Compilation database generation
- Using CMake (version 3.5 and above):
- For projects that use CMake, passing -DCMAKE_EXPORT_COMPILE_COMMANDS=ON to cmake command generates the compile_commands.json file into the current directory.
Note: This option is implemented only by Makefile Generators and the Ninja. It is ignored by other generators.
Example:
$ cd path/to/source/directory
$ cmake
[options] -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
Using intercept-build:
- Introduction: Intercept-build uses two modes to generate the compilation database:
- Use a special library to intercept compiler calls during the build process.
- Use compiler wrappers to intercept compiler calls during the build process. The 1st mode is available only on FreeBSD, Linux and OSX. Where library preload is available from the dynamic loader. Security extension/modes on different operating systems might disable library preload. In this case, the build behaves normally, but the result compilation database will be empty. (Notable examples for enabled security modes are: SIP on OS X Captain and SELinux on Fedora, RHEL and CentOS.) The program checks the security modes for SIP and falls back to the next mode. Note: Refer the troubleshooting section below to solve the problem above. The 2nd mode works only if the build process respects the CC and CXX environment variables. (Some build process can override these variables as command line parameter only. This case you need to pass the compiler wrappers manually. e.g.: intercept-build –override-compiler make CC=intercept-cc CXX=intercept-c++ all where the original build command would have been make all only.) This is the default behavior, which can be enforced with the –override-compiler lag.
- Portability: Intercept-build should be quite portable on UNIX operating systems. It has been tested on FreeBSD, GNU/Linux and OS X.
- Prerequisites: python interpreter (version 2.7, 3.3, 3.4, 3.5)
- Location: The intercept-build tool is packaged along with the distribution archive (corona).
- Steps to generate a compilation database:
- Unzip the distribution zip which contains the intercept-build tool at this location – corona/cxxparser/trace-utility/bin
- Prepend intercept-build to build command:
$ cd path/to/source/directory
$ corona/cxxparser/trace-utility/bin/intercept-build
- Examples:
$ cd path/to/source/directory
$ make clean
$ intercept-build make
$ cd path/to/source/directory
$ scons –c
$ intercept-build scons
$ cd path/to/source/directory
$ gmake clean
$ intercept-build gmake
- Examples of using custom compiler: When build system uses CC variable and it is defined as environment variable
$ intercept-build --use-cc=""pathtocompilerexecutable"" make
When build system uses CC variable and it is defined as command line parameter (inside build script)$ intercept-build --use-cc=""pathtocompilerexecutable"" make CC=intercept-cc
When build system uses e.g.: MP_CC (other than CC) variable and its defined as command line parameter (inside build script)$ intercept-build --use-cc=""pathtocompilerexecutable"" make MP_CC=intercept-cc
The output file called compile_commands.json will be found in the current directory. - Common issues
- Problems caused by environment overriding: Because intercept-build uses LD_PRELOAD or DYLD_INSERT_LIBRARIES environment variables, it does not append to it, but overrides it. So, builds that are using these variables might not work.
- Troubleshooting: To overcome the empty compilation database problem on Fedora, CentOS and RHEL you should disable SELinux. To disable SELinux, follow the procedure below:
- Configure SELINUX=disabled in the /etc/selinux/config file:
- Reboot your system. After reboot, confirm that the get enforce command returns Disabled.
- Run intercept build.
- Configure SELINUX=disabled in the /etc/selinux/config file:
- Using WAF: WAF is a Python-based framework for configuring, compiling and installing applications. WAF build system has inbuilt support for generating a compilation database. Add an option under ‘configure’ step in top-level wscript file as shown in image attached.
Also, WAF is module-based, so clang_compilation_database.py module should be present in the lib folder. Location of lib folder should look like the following: [project-top-level-directory] /waflib/extras/ compile_commands.json should be generated after a successful build.