FAQs
What tools are available for generating the compile_commands.json
file?
There are several tools available to generate the compile_commands.json
file. Here's a list of common tools, along with their compatibility across the different operating systems:
Tool | Description | Linux | Windows |
---|---|---|---|
CMake | Built-in support to generate the compile_commands.json | ✔ | ✔* |
Bear | Works with Makefile-based projects, intercepts build commands. | ✔ | ✘ |
Scons | Built-in support to generate the compile_commands.json | ✔ | ✔ |
Clang Power Tools | Visual Studio extension with a simplified interface. | ✔ | ✔ |
Ninja | Requires a Ninja build system setup. | ✔ | ✔ |
meson | Build-system that generates compile_commands.json by default | ✔ | ✔ |
Bazel | Build-system that can generate the compile_commands.json | ✔ | ✔ |
CompDB | Works for various build systems. | ✔ | ✔ |
* Note: Cmake only works in Windows for Ninja generators (cmake -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
)
What information is store in the compile_commands.json
file?
Here are some examples of compile_commands.json
files.
Example of a compile_commands.json
generated with CMake:
[
{
"directory": "/home/user/Appentra/repos/performance-demos/MATMUL/serial/build",
"command": "/usr/bin/gcc -I/home/user/Appentra/repos/performance-demos/MATMUL/serial/include -O3 -DNDEBUG -fopenmp -o CMakeFiles/matmul.dir/matrix.c.o -c /home/user/Appentra/repos/performance-demos/MATMUL/serial/matrix.c",
"file": "/home/user/Appentra/repos/performance-demos/MATMUL/serial/matrix.c"
},
{
"directory": "/home/user/Appentra/repos/performance-demos/MATMUL/serial/build",
"command": "/usr/bin/gcc -I/home/user/Appentra/repos/performance-demos/MATMUL/serial/include -O3 -DNDEBUG -fopenmp -o CMakeFiles/matmul.dir/clock.c.o -c /home/user/Appentra/repos/performance-demos/MATMUL/serial/clock.c",
"file": "/home/user/Appentra/repos/performance-demos/MATMUL/serial/clock.c"
},
{
"directory": "/home/user/Appentra/repos/performance-demos/MATMUL/serial/build",
"command": "/usr/bin/gcc -I/home/user/Appentra/repos/performance-demos/MATMUL/serial/include -O3 -DNDEBUG -fopenmp -o CMakeFiles/matmul.dir/main.c.o -c /home/user/Appentra/repos/performance-demos/MATMUL/serial/main.c",
"file": "/home/user/Appentra/repos/performance-demos/MATMUL/serial/main.c"
}
]
Example of a compile_commands.json
generated with Bear:
[
{
"arguments": [
"/usr/bin/cc",
"-c",
"-I",
"include",
"-fopenmp",
"-O3",
"-o",
"matmul",
"matrix.c"
],
"directory": "/home/user/Appentra/repos/performance-demos/MATMUL/serial",
"file": "/home/user/Appentra/repos/performance-demos/MATMUL/serial/matrix.c",
"output": "/home/user/Appentra/repos/performance-demos/MATMUL/serial/matmul"
},
{
"arguments": [
"/usr/bin/cc",
"-c",
"-I",
"include",
"-fopenmp",
"-O3",
"-o",
"matmul",
"clock.c"
],
"directory": "/home/user/Appentra/repos/performance-demos/MATMUL/serial",
"file": "/home/user/Appentra/repos/performance-demos/MATMUL/serial/clock.c",
"output": "/home/user/Appentra/repos/performance-demos/MATMUL/serial/matmul"
},
{
"arguments": [
"/usr/bin/cc",
"-c",
"-I",
"include",
"-fopenmp",
"-O3",
"-o",
"matmul",
"main.c"
],
"directory": "/home/user/Appentra/repos/performance-demos/MATMUL/serial",
"file": "/home/user/Appentra/repos/performance-demos/MATMUL/serial/main.c",
"output": "/home/user/Appentra/repos/performance-demos/MATMUL/serial/matmul"
}
]
The main difference between the two examples is that bear uses the "arguments" terminology whereas CMake uses "command". The clang community prefers the use of Bear because of this, as shell (un)escaping is a possible source of errors. Clang 20.0.0 documentation
How to apply Codee filters?
In some cases, users may want to apply filters to the Codee invocation to analyze certain files instead of the entire project. To do this, refer to the following example;
codee screening file1.F90 file2.F90 --compile-commands compile_commands.json
With the command above, the screening output will only report information related to file1.F90
and file2.F90
.
Additional filters can be applied, allowing users to target specific loops or functions, limiting the resulting checkers to those that reference the specified sections. For example, to see the checkers that reference function1
in file1.F90
, use the following command:
codee checks file1.F90:function1 --compile-commands compile_commands.json
To apply a filter for a specific loop, specify the line where the loop begins. For instance, if the loop starts at line 30, use this command:
codee checks file1.F90:30 --compile-commands compile_commands.json
How to analyze only the files that have changed?
As a developer, it might be interesting to analyze only the files with changes in a Git repository. The following Bash script demonstrates how to use Codee to analyze only the subset of source files with unstaged changes:
#!/bin/bash
# List all unstaged source files with changes
changed_files=$(git diff --name-only --diff-filter=M | grep -E '\.(c|cpp|F90|f90)$')
# Check if there are any changed files
if [ -z "$changed_files" ]; then
echo "No unstaged changes found in source files."
exit 0
fi
# Run Codee with the list of changed files
codee screening $changed_files --compile-commands compile_commands.json
-
git diff --name-only --diff-filter=M
retrieves the list of modified files with unstaged changes. -
grep -E '\.(c|cpp|F90|f90)$'
filters this list, selecting only source files with specific extensions. -
Finally, the scripts runs
codee screening
on the filtered list of files, allowing Codee to only analyze those files with unstaged modifications.
* Note: Update the file extensions in the grep command based on your source file types (e.g., .f
, .f90
, .F90
). Also, make sure to specify the correct path to your
compile_commands.json
file if it is located elsewhere in your project. You can also modify the codee command to select another mode, for example, codee checks
.
This script is easily customizable and helps streamline the analysis process, ensuring that Codee is only targeting the files you're actively working on.