Static analysis#

LIBRA makes static analysis nearly zero-configuration: enable LIBRA_ANALYSIS and the targets appear automatically for every tool found on PATH. This page explains the design decisions behind that behaviour. For the target reference and the mechanics of header coverage, see Target reference.

How LIBRA configures analysis#

LIBRA detects the languages enabled for your CMake project and sets the source files passed to each analysis tool accordingly. This allows tools that only support C or C++ to coexist without causing errors on incompatible source files.

An individual target is created per auto-registered source file, giving you per-file warnings and errors — the same granularity as compilation.

Analysis is a separate workflow#

Analysis is a separate workflow from the usual debug/test cycle and should run in its own preset and build directory. This is not merely a conceptual preference — it is a correctness requirement for the fix targets. Running fix targets against a stale build that does not reflect current source can produce incorrect patches (see Analysis internals: header stubs and the fix targets).

It is (highly) unlikely that a given project will want to require that ALL static analysis checks pass for MR merge, etc. Many of the checks overlap with each other (esp. clang-tidy), so it is up to each project to choose which checks to use.

Compilation database#

By default, analysis tools consume a compilation database (compile_commands.json), which is the most reliable source of truth for compiler flags, include paths, and defines. Keeping LIBRA_USE_COMPDB =YES (the default) is strongly recommended — especially for projects with layered PRIVATE dependencies, where the non-compdb path cannot see the full flag set. The exact fallback behaviour is documented in Analysis internals: header stubs and the fix targets.

Note

For best results, set the compiler to clang when using clang-based tools such as clang-tidy. If the compiler is not clang, the compilation database may contain flags that clang does not understand, causing analysis to fail even if the project builds cleanly. Using LIBRA_USE_COMPDB =YES is strongly recommended if using GCC for builds and clang for analysis.

Header files must be self-contained#

Header files are always required to be syntactically self-contained and valid in isolation — they must not rely on a specific include order or on definitions provided by a prior #include. This is enforced directly by LIBRA’s analysis machinery.

Headers that are consumed by a .c/.cpp translation unit are analyzed in that context automatically. Public headers that no translation unit includes — as in header-only libraries — are covered by a generated stub translation unit so they receive correct flags and are analyzed like any other source. If a header fails analysis, that is a real bug in the header; the fix is to make it self-contained, not to suppress the error.

The full stub-generation mechanism, and why it requires a fresh configure before every fix-* run, is documented in Analysis internals: header stubs and the fix targets.