Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Introduction

This section describes how to integrate C/C++test CT with a Bazel build for running static analysis and code coverage.

Prerequisites

  • Supported Bazel major versions: 6.x, 7.x, and 8.x (Bazel 9+ is not supported)
  • C/C++test for Linux (Windows is not supported)
  • The integration is designed to work with rules that are derived from cc_library, cc_binary, and cc_test.

Adding a C/C++test CT Installation as a Bazel Local Repository

A clean installation of C/C++test CT will not immediately work as a Bazel local repository. Follow the procedure below to add a C/C++test CT installation as a Bazel local repository.

  1. Move the WORKSPACE.bazel, BUILD.bazel, and MODULE.bazel files located in the integration/bazel directory to the root of the C/C++test CT installation.
    Code Block
    cd <INSTALL_DIR>
    mv integration/bazel/WORKSPACE.bazel .
    mv integration/bazel/BUILD.bazel .
    mv integration/bazel/MODULE.bazel .
    Note: Make sure the files are moved and no copy remains in the integration/bazel directory.
  2. Open the Bazel WORKSPACE file at the root of your project.
  3. Register the C/C++test CT installation as a Bazel local repository in your WORKSPACE file.

    Code Block
    local_repository(name = "cpptest", path = "<INSTALL_DIR>")
  4. If you are using Bazel modules, register the C/C++test installation as a Bazel dependency in your MODULE file.
    Code Block
    bazel_dep(
        name = "cpptest",
    )
    local_path_override(
        module_name = "cpptest",
        path = "<INSTALL_DIR>",
    )

Example Build Target

The following example will be used in the subsequent procedures:

Code Block
cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
    deps = [
        ":hello-greet",
    ],
)

Generating an Executable with Code Coverage

Follow the procedure below to generate a test binary with code coverage instrumentation

  1. Generate the instrumented artifacts (instrument-only).

    Code Block
    bazel run @cpptest//:coverage --@cpptest//:target=//:hello-world --@cpptest//:compiler-config=gcc_10-64 --@cpptest//:line-coverage

    • "@cpptest//:coverage" is a collector-only entry point; it does not execute the instrumented binary.
    • The executable generated will be of the form "<TARGET_NAME>.elf" and will be located in the bazel-bin directory next to where a binary would typically be generated. In the above example, it will be hello-world.elf.
    • The integration will not run the instrumented executable.
  2. Execute the instrumented binary.

    Code Block
    bazel-bin/hello-world.elf
  3. Generate coverage data files.

    Code Block
    cpptestcov compute -map .cpptest -clog cpptest_results.clog -out .coverage
  4. Generate a coverage report.

    Code Block
    cpptestcov report text .coverage

Note: When generating coverage data for a Bazel project, C/C++test CT will resolve symbolic links in the file paths. To keep the symbolic links unresolved, define the following environment variable before generating the coverage data files.

Code Block
export CPPTEST_COVERAGE_SRC_ROOT_RESOLVE_SYMLINKS=false

Anchor
Configuring the Coverage Instrumentation Tool (cpptestcc)
Configuring the Coverage Instrumentation Tool (cpptestcc)
Configuring the Coverage Instrumentation Tool (cpptestcc) 

You can configure the coverage instrumentation tool (cpptestcc) using a .psrc configuration file.

  1. Copy the example .psrc file to the project.

    Code Block
    cp <INSTALL_DIR>/integration/bazel/cpptestcc-bazel.psrc <PROJECT_ROOT>/cpptestcc-bazel.psrc
  2. Modify the contents of cpptestcc-bazel.psrc, as needed. For a list of options, see Command Line Reference for cpptestcc or run:
    Code Block
    cpptestcc -help
  3. Define the "cpptestcc-bazel-psrc" filegroup in your BUILD.bazel file that refers to the cpptestcc-bazel.psrc file.

    Code Block
    filegroup(name = "cpptestcc-bazel-psrc", srcs = ["cpptestcc-bazel.psrc"], visibility = ["//visibility:public"])
  4. Use the "--@cpptest//:psrc_file" option with the "cpptestcc-bazel-psrc" filegroup when executing the "@cpptest//:coverage" rule.

    Code Block
    bazel run @cpptest//:coverage --@cpptest//:target=//:hello-world --@cpptest//:psrc_file=//:cpptestcc-bazel-psrc

Configuration Options for C/C++test's Bazel Rules

Common Arguments

Option

Description

--@cpptest//:target=<TARGET>

Specifies the target rule to be analyzed. A project rule of the type "cc_*" or a type derived from it should be specified.
Default: None
Example: --@cpptest//:target=//main:hello-world

--@cpptest//:psrc_file=<CUSTOM_PSRC_FILEGROUP>

Specifies the filegroup for the .psrc configuration file; see Configuring the Coverage Instrumentation Tool (cpptestcc).
Default: None
Example: --@cpptest//:psrc_file=//:cpptestcc-bazel-psrc

Before using this option, be sure to define the filegroup that refers to the .psrc configuration file in your BUILD.bazel file. For example:
filegroup(name = "cpptestcc-bazel-psrc", srcs = ["cpptestcc-bazel.psrc"], visibility = ["//visibility:public"])
See the cpptestcc-bazel.psrc file located in <INSTALL_DIR>/integration/bazel for more information.

"@cpptest//:coverage" Rule Arguments

Option

Description

--@cpptest//:compiler-config=<COMPILER_CONFIGURATION_NAME>

Specifies the compiler configuration.
This argument is mandatory unless the compiler configuration is specified in the .psrc file; see Configuring the Coverage Instrumentation Tool (cpptestcc).
Default: None
Example: --@cpptest//:compiler-config=clang_12_0

--@cpptest//:line-coverage
--@cpptest//:optimized-line-coverage
--@cpptest//:function-coverage
--@cpptest//:optimized-function-coverage
--@cpptest//:statement-coverage
--@cpptest//:optimized-statement-coverage
--@cpptest//:block-coverage
--@cpptest//:optimized-block-coverage
--@cpptest//:simple-condition-coverage
--@cpptest//:optimized-simple-condition-coverage
--@cpptest//:decision-coverage
--@cpptest//:optimized-decision-coverage
--@cpptest//:call-coverage
--@cpptest//:optimized-call-coverage

--@cpptest//:mcdc-coverage

Enables specific coverage metric(s).

This is mandatory unless it is specified in the .psrc file; see Configuring the Coverage Instrumentation Tool (cpptestcc).

--@cpptest//:verbose

Enables verbose console output for all stages of cpptestcc instrumentation and compilation.
Default: False

--@cpptest//:quiet

Suppresses all console text output from the cpptest engine during execution.
Default: False

Example of Integrating with Bazel Project

This example uses C/C++test CT coverage plugin for Bazel.

  1. Move <INSTALL_DIR>/integration/bazel/WORKSPACE.bazel and <INSTALL_DIR>/integration/bazel/BUILD.bazel into the C/C++test CT installation directory. 
    Note: Make sure the files are moved and no copy remains in the integration/bazel directory.
  2. Go to <INSTALL_DIR>/examples/CovApplication
  3. Build the project with coverage enabled.
    Code Block
    bazel run --config=cpptest_coverage
  4. Execute the instrumented application.
    Code Block
    bazel-bin/Timer.elf
  5. Generate coverage data files into .coverage.
    Code Block
    cpptestcov compute -map .cpptest -clog cpptest_results.clog -out .coverage
  6. Report coverage statistics for .coverage.
    Code Block
    cpptestcov report text .coverage

See the README.txt file located in <INSTALL_DIR>/integration/bazel for more details.