API#
LIBRA API Conventions#
All public API functions/macros start with
libra_; anything else is non-API and can change at any time.All public API variables start with
LIBRA_; anything else is non-API and can change at any time.All private API functions/macros start with
_libra_. They should never be used outside of LIBRA itself.All private API variables start with
_LIBRA_. They should never be used outside of LIBRA itself. Private API variables are ones which have some semantic significance beyond just a temp variable for calculations.
LIBRA Private API#
Analysis#
- _libra_register_code_checkers#
Registers all code-checking analysis tools (distinct from documentation checking analysis tools). Currently this is:
cppcheck. Operates on sources and stubs.
clang-tidy. Operates on sources, headers, and stubs.
clang-check. Operates on sources and stubs.
- Param TARGET:
The name of the target {sources,headers,stubs} are attached to.
- Param SRCS:
Source files for checkers to check.
- Param HEADERS:
Header files for checkers to check.
- Param STUBS:
Stub C/C++ files which include a single header for checkers to check. Used to check headers which aren’t included in any source file and thus don’t have compdb entries.
- _libra_register_code_fixers#
Registers all code-fixing analysis tools. Currently this is:
clang-tidy
clang-check
Fixing is limited to source files because fixing with raw header files and/or stubs is not very reliable.
- Param TARGET:
The name of the target {sources,headers,stubs} are attached to.
- Param SRCS:
Source files for checkers to check.
- _libra_header_needs_stub#
Determine if a header file in the project needs a stub created for it so that analysis works reliably with a compilation database. A header needs a stub if it isn’t included in any source file in the project.
This is done by checking through every source file to see if a given header appears in it relative to a given interface include directory.
- Param HEADER:
The header to check the status of.
- Param PARENT:
The parent interface include directory to check against.
- Param RET:
Name of variable in parent scope to set with yes/no.
- _libra_prune_stale_stubs#
Remove stub files from STUB_DIR that no longer correspond to any header in the current project.
Called before _libra_generate_header_stubs so that stubs for removed or renamed headers don’t accumulate across reconfigures. Relies on the same naming convention used by _libra_generate_header_stubs to reconstruct the expected stub filename from each header path.
This approach was chosen over nuking the stub directory on every configure for a few reasons:
The unconditional delete violates incremental build principles. CMake’s configure step is supposed to be idempotent and cheap for unchanged inputs. Unconditionally deleting and regenerating all stubs means every cmake configure run with LIBRA_ANALYSIS=YES invalidates all stub object files, forcing a full stub recompile before any analysis can run — even if zero headers changed. For a project with hundreds of public headers this becomes a meaningful tax on every analysis run.
The IS_NEWER_THAN mechanism already exists for a reason: to avoid unnecessary regeneration. The unconditional delete defeats it entirely, making it dead code in practice.
This approach composes better with –fresh. A –fresh configure already wipes the binary directory entirely, so stale stubs are cleaned up naturally. The unconditional delete is redundant in the –fresh case and harmful in the incremental case.
- Param TARGET:
The CMake target whose public headers define the expected stub set.
- Param STUB_DIR:
Directory containing existing stubs to prune.
- _libra_generate_header_stubs#
Generate stub .cpp files for standalone header analysis.
Each stub contains a single #include of its corresponding header, expressed as a path relative to the include directory it was found under. This ensures the header is analyzed with the same include path form as real consumers would use, and that any missing self-containment or include-order bugs are caught as real errors rather than papered over.
Stubs are written to STUB_DIR and only regenerated if the header is newer than the existing stub, avoiding spurious rebuilds.
Only headers under the target’s INTERFACE_INCLUDE_DIRECTORIES are stubbed, which is correct: those are the headers that form the public API and must be self-contained. Private/internal headers that are not exposed via INTERFACE_INCLUDE_DIRECTORIES are intentionally excluded.
- Param TARGET:
The CMake target whose public headers are stubbed.
- Param STUB_DIR:
Directory under which stub .cpp files are written. Typically ${CMAKE_BINARY_DIR}/libra_header_stubs.
- Param STUBS_VAR:
Name of the variable in caller’s scope that receives the list of generated stub file paths.
- analyze_build_fixeddb_for_target#
Build a fixed compilation database (LLVM/clang terminology) for a target. A fixed compdb is the set of includes and #define which would otherwise be pulled out of the compilation database. These are then passed to the analysis tool just as they would be to the compiler. In theory this should be the same as a compilation database, but isn’t necessarily guaranteed to be.
The magic here is that we create a fake interface target to force transitive resolution of interface {include dirs, definitions}. Without this, we have to walk the PRIVATE deps of TARGET, which is bad, or be limited to a single level of resolution, which isn’t sufficient for complex projects.
- Param TARGET:
The target to build a fixeddb for.
- Param RET:
Name of variable to set in parent scope with the args to add to the analysis tool.
- analyze_build_adhocdb_for_target#
Same as
analyze_build_fixeddb_for_target(), but clang tools only. Instead of fixeddb, we build a set of--extra-argarguments which are passed en masse to clang tools. In theory this should be the same as a compilation database, but isn’t necessarily guaranteed to be.- Param TARGET:
The target to build a adhocdb for.
- Param RET:
Name of variable to set in parent scope with the args to add to the analysis tool.
- analyze_clang_extract_args_from_target#
For clang-based analysis tools, extract necessary args for a target so that analysis will work on all input files.
This can be:
Telling the tool to use a compdb (default).
Telling the tool to use a fixed compdb via
LIBRA_CLANG_TOOLS_USE_FIXED_DB.Telling the tool to use an adhocdb via
LIBRA_CLANG_TOOLS_USE_FIXED_DB.
- Param TARGET:
The target to extract args from.
- Param RET:
Name of variable to set in parent scope with the args to add to the analysis tool.
- _libra_find_code_analyzers#
Finds acceptable versions of all analysis tools libra uses for analyze code.
Currently this is:
clang-tidy
clang-check
cppcheck
- _libra_find_apidoc_analyzers#
Finds acceptable versions of all analysis tools libra uses for analyze documentation.
Currently this is:
clang
doxygen
Formatting#
- _libra_find_formatting_tools#
Finds acceptable versions of all formatting tools LIBRA uses.
Currently this is:
clang-format
cmake-format