OCLint

Using oclint-json-compilation-database

OCLint needs a compilation database to figure out the compiler options for parsing each file, so that it can run more accurate analysis on an intermediate representation of the source code. This document provides instructions about generating compile_commands.json (JSON Compilation Database), and use oclint-json-compilation-database for code analysis.

JSON Compilation Database

A JSON Compilation Database, file name compile_commands.json, maintains a list of source code files with related build options. For each source file, working directory and command for compiling the source code are explicitly given. For example:

[
    {
      "directory": "/Projects/oclint/build",
      "command": "/Projects/llvm/bin/clang++   -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS  -O0 -g -fno-rtti -Wno-c++11-extensions -fPIC -I/Projects/llvm/include -I/Projects/oclint/headers -o CMakeFiles/oclint.dir/main.cpp.o -c /Projects/oclint/main.cpp",
      "file": "/Projects/oclint/main.cpp"
    },
    {
      "directory": "/Projects/oclint/build/impl/core",
      "command": "/Projects/llvm/bin/clang++   -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS  -O0 -g -fno-rtti -Wno-c++11-extensions -fPIC -I/Projects/llvm/include -I/Projects/oclint/headers -o CMakeFiles/OCLintCore.dir/Violation.cpp.o -c /Projects/oclint/impl/core/Violation.cpp",
      "file": "/Projects/oclint/impl/core/Violation.cpp"
    },
    {
      "directory": "/Projects/oclint/build/impl/core",
      "command": "/Projects/llvm/bin/clang++   -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS  -O0 -g -fno-rtti -Wno-c++11-extensions -fPIC -I/Projects/llvm/include -I/Projects/oclint/headers -o CMakeFiles/OCLintCore.dir/ViolationSet.cpp.o -c /Projects/oclint/impl/core/ViolationSet.cpp",
      "file": "/Projects/oclint/impl/core/ViolationSet.cpp"
    }
]

See JSON Compilation Database Format Specification with more precise defination.

Generating JSON Compilation Database

There are three approaches for generating JSON Compilation Database - writing your own, using CMake, and using OCLint xcodebuild helper program.

Writing Your Own

You can follow the format defined in JSON Compilation Database Format Specification, and write your own compile_commands.json file. It is convenient when you have a few sources to inspect.

You certainly need some tools’ help if you have a large project.

Using CMake

CMake is a cross-platform build system. It can also help generate the required compile_commands.json compilation database.

Read CMake Documentation about how to use CMake as your build system.

You need to tell CMake that you are expecting compile_commands.json to be generated, so that when CMake converts its CMakeLists.txt to regular Makefile, it outputs compile_commands.json file for you along the way. To do this, add one extra option to you CMake command, for example:

cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON path/to/source-root

As a result, the compile_commands.json file is generated in current folder.

You can leave it here in the build directory, and use -p option for oclint to specify this file.

But in order to use oclint-json-compilation-database, it’s required to copy or link this file to your source directory, for example:

ln -s `pwd`/compile_commands.json /path/to/source-root

Using OCLint xcodebuild Helper Program

If you are a Xcode user, then we have a helper program that extracts adequate compiler options and convert them into compile_commands.json file. Read how to use oclint-xcodebuild for instructions.

oclint-json-compilation-database Usage

Since you have compile_commands.json file copied or linked, you can now simply run oclint-json-compilation-database in your source directory. It reads the compile_commands.json file, get the list of all source files, and pass them to oclint for analysis.

See the usage by typing oclint-json-complication-database -help:

usage: oclint-json-compilation-database [-h] [-v] [-i INCLUDES] [-e EXCLUDES]
                                    [oclint_args [oclint_args ...]]

OCLint for JSON Compilation Database (compile_commands.json)

positional arguments:
  oclint_args           arguments that are passed to OCLint invocation

optional arguments:
  -h, --help            show this help message and exit
  -v                    show invocation command with arguments
  -i INCLUDES, -include INCLUDES, --include INCLUDES
                        extract files matching pattern
  -e EXCLUDES, -exclude EXCLUDES, --exclude EXCLUDES
                        remove files matching pattern

Filter Options

-i INCLUDES, -include INCLUDES, –include INCLUDES
Extract files matching pattern from compile_commands.json or prior matching result
-e EXCLUDES, -exclude EXCLUDES, –exclude EXCLUDES
Remove files matching pattern from compile_commands.json or prior matching result

Sometimes, you may be interested in a subset of entire codebase defined in compile_commands.json, and just want to inspect these sources. To do that, you can use filter options to get this subset. Since oclint-json-compilation-database is written in Python, so the matching pattern needs to follow Python regular expression syntax. In addition, multiple filters can be chained to get the file set you need for analysis.

OCLint Options

Remember there are many options that you can use to change the behavior of OCLint itself? Sure, you can ask oclint-json-compilation-database to pass through these options when it invokes oclint under the hook.

Since you have all compiler options in compile_commands.json file, so this time you don’t need to tell oclint about them. But by following the same idea, now, these OCLint options can be given directly to oclint-json-compilation-database by appending -- separator followed by all OCLint options:

oclint-json-compilation-database [<filter0> ... <filterN>] -- [oclint options]

Debug Options

-v
show invocation command with arguments

Debug options are used for you to see the final oclint invocation command according to your settings of all filters and OCLint options. If you run the generated oclint command directly in the console, you should get the identical result as using oclint-json-compilation-database.