Implementing clang based code coverage in custom Bazel C rules

Viewed 307

I am trying to get bazel coverage //my:test to output coverage data files, building with custom C rules and using a custom clang toolchain.

For Bazel's native C rules this is a solved problem. I can build coverage output using the cc_library and cc_test native rules by running the following command with env set:

export BAZEL_USE_LLVM_NATIVE_COVERAGE=1
export GCOV=/path/to/llvm-profdata
export BAZEL_LLVM_COV=/path/to/llvm-cov
export CC=/path/to/clang

bazel coverage //my:test --experimental_generate_llvm_lcov --combined_report=lcov

The test target has a coverage.dat file output and there is a combined dat report file too. I have noticed that the cc_library target returns an InstrumentedFilesInfo provider that has the "metadata files" attribute populated with the .gcno files output during compilation.


I am using the cc_common Starlark library to build custom C rules and my compile action is setup via cc_common.compile(). While *.gcno files are outputs that Bazel expects from this action [0], the compile function does not return any *.gcno File objects in the compilation context or compilation output so using them as the inputs to another action/returning in a provider/adding to the target's runfiles is not possible.

I understand that the .dat files are produced using the *.gcno compile output and the *.gcda sandboxed test execution output and combined in the collect_cc_coverage.sh script. Something in the plumbing of my rule implementation is missing that is not being fixed by returning a provider constructed by coverage_common.instrumented_files_info() and declaring extra outputs of cc_common.compile() is currently not possible.

[0]: Running under coverage rather than test has the toolchain feature where --compile is added the .gcno files are output and they appear in bazel-out.

My questions:

  • Has anyone had any experience implementing code coverage for custom C rules?
  • How do I get my test executable to take in .gcno files, generate the .gcda files and combine the two using my toolchain to produce the .dat files that are expected with the native C rules? (This question does not require .gcno - solutions involving profraw/profdata are equally valid.)
0 Answers
Related