Code coverage#

LIBRA supports three coverage toolchains: gcovr, lcov, and llvm-cov. This page covers when to use each, how to configure thresholds, and how to generate and view reports.

For the target reference, see Target reference. For the flag reference, see coverage.

Choosing a tool#

Tool

Format

Use when

gcovr

GNU (GCC or Clang with -fprofile-arcs)

You want threshold checking (gcovr-check) or fast HTML reports. Works with both GCC and Clang. The ci workflow uses gcovr-check by default.

lcov

GNU

You need an absolute report that shows files with 0% coverage. gcovr-report only shows files that were executed; lcov-report shows everything.

llvm-cov

LLVM native (Clang only)

You are building with Clang and want source-level coverage highlighting or integration with LLVM tooling.

Set LIBRA_COVERAGE_NATIVE to control which format is generated. The default (YES) means GCC uses GNU format and Clang uses LLVM format. Set it to NO to force GNU format from both compilers.

1. Add a coverage preset#

{
  "configurePresets": [
    {
      "name": "coverage",
      "inherits": "base",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Debug",
        "LIBRA_TESTS":    "ON",
        "LIBRA_COVERAGE": "ON"
      }
    }
  ],
  "buildPresets": [
    { "name": "coverage", "configurePreset": "coverage" }
  ],
  "testPresets": [
    {
      "name": "coverage",
      "configurePreset": "coverage",
      "output": { "outputOnFailure": true }
    }
  ]
}

2. Configure thresholds#

Set these in cmake/project-local.cmake. The gcovr-check target fails if any threshold is not met:

set(LIBRA_GCOVR_LINES_THRESH     80)   # default: 95
set(LIBRA_GCOVR_FUNCTIONS_THRESH 70)   # default: 60
set(LIBRA_GCOVR_BRANCHES_THRESH  50)   # default: 50
set(LIBRA_GCOVR_DECISIONS_THRESH 50)   # default: 50

Start with lower thresholds and raise them incrementally as you add tests. Setting them too high initially makes CI fail immediately on a new project.

3. Generate an HTML report#

clibra coverage --preset coverage          # generate report
clibra coverage --preset coverage --open   # generate and open

clibra coverage discovers the first available HTML target (gcovr-report then llvm-report) automatically.

cmake --preset coverage
cmake --build --preset coverage --target all-tests
ctest --preset coverage
cmake --build --preset coverage --target gcovr-report

Report opens at build/coverage/coverage/index.html.

cmake --preset coverage
cmake --build --preset coverage --target all-tests
cmake --build --preset coverage --target lcov-preinfo
ctest --preset coverage
cmake --build --preset coverage --target lcov-report

lcov-preinfo must run before the tests to capture the 0% baseline. Omitting it produces a relative report identical to gcovr-report.

Requires Clang and LIBRA_COVERAGE_NATIVE=YES (the default):

cmake --preset coverage
cmake --build --preset coverage --target all-tests
ctest --preset coverage
cmake --build --preset coverage --target llvm-coverage

llvm-coverage runs llvm-report (HTML) and llvm-summary (terminal) in sequence.

Warning

Run test binaries from the build directory root so that .profraw files land in PROJECT_BINARY_DIR. llvm-profdata looks for them there.

4. Check coverage thresholds#

clibra coverage --preset coverage --check
cmake --build --preset coverage --target gcovr-check

The target exits non-zero if any threshold is not met, printing which metric failed and by how much.

5. Full CI workflow#

The recommended CI coverage sequence:

clibra ci --preset ci   # build + test + gcovr-check in one command

Requires a ci workflow preset. See CI setup.

cmake --preset ci
cmake --build --preset ci --target all-tests
ctest --preset ci
cmake --build --preset ci --target gcovr-check