Skip to content

Commit b96f1a6

Browse files
committed
add clang/llvm based coverage report generation
Signed-off-by: Prabhat Verma <prabhatverma329@gmail.com>
1 parent 83a9e55 commit b96f1a6

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

doc/developer-notes.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,8 @@ $ ./build/test/functional/test_runner.py --valgrind
484484

485485
### Compiling for test coverage
486486

487+
#### Using LCOV
488+
487489
LCOV can be used to generate a test coverage report based upon `ctest`
488490
execution. LCOV must be installed on your system (e.g. the `lcov` package
489491
on Debian/Ubuntu).
@@ -513,6 +515,63 @@ To enable test parallelism:
513515
cmake -DJOBS=$(nproc) -P build/Coverage.cmake
514516
```
515517

518+
#### Using LLVM/Clang toolchain
519+
520+
The following generates a coverage report for unit tests and functional tests.
521+
522+
Configure the build with the following flags:
523+
524+
> Consider building with a clean state using `rm -rf build`
525+
526+
```shell
527+
# MacOS may instead require `-DCMAKE_C_COMPILER="$(brew --prefix llvm)/bin/clang" -DCMAKE_CXX_COMPILER="$(brew --prefix llvm)/bin/clang++"`
528+
cmake -B build -DCMAKE_C_COMPILER="clang" \
529+
-DCMAKE_CXX_COMPILER="clang++" \
530+
-DAPPEND_CFLAGS="-fprofile-instr-generate -fcoverage-mapping" \
531+
-DAPPEND_CXXFLAGS="-fprofile-instr-generate -fcoverage-mapping" \
532+
-DAPPEND_LDFLAGS="-fprofile-instr-generate -fcoverage-mapping"
533+
cmake --build build # Use "-j N" here for N parallel jobs.
534+
```
535+
536+
Generating the raw profile data based on `ctest` and functional tests execution:
537+
538+
```shell
539+
# Create directory for raw profile data
540+
mkdir -p build/raw_profile_data
541+
542+
# Run tests to generate profiles
543+
LLVM_PROFILE_FILE="$(pwd)/build/raw_profile_data/%m_%p.profraw" ctest --test-dir build # Use "-j N" here for N parallel jobs.
544+
LLVM_PROFILE_FILE="$(pwd)/build/raw_profile_data/%m_%p.profraw" build/test/functional/test_runner.py # Use "-j N" here for N parallel jobs
545+
546+
# Merge all the raw profile data into a single file
547+
find build/raw_profile_data -name "*.profraw" | xargs llvm-profdata merge -o build/coverage.profdata
548+
```
549+
550+
> **Note:** The "counter mismatch" warning can be safely ignored, though it can be resolved by updating to Clang 19.
551+
> The warning occurs due to version mismatches but doesn't affect the coverage report generation.
552+
553+
Generating the coverage report:
554+
555+
```shell
556+
llvm-cov show \
557+
--object=build/bin/test_bitcoin \
558+
--object=build/bin/bitcoind \
559+
-Xdemangler=llvm-cxxfilt \
560+
--instr-profile=build/coverage.profdata \
561+
--ignore-filename-regex="src/crc32c/|src/leveldb/|src/minisketch/|src/secp256k1/|src/test/" \
562+
--format=html \
563+
--show-instantiation-summary \
564+
--show-line-counts-or-regions \
565+
--show-expansions \
566+
--output-dir=build/coverage_report \
567+
--project-title="Bitcoin Core Coverage Report"
568+
```
569+
570+
> **Note:** The "functions have mismatched data" warning can be safely ignored, the coverage report will still be generated correctly despite this warning.
571+
> This warning occurs due to profdata mismatch created during the merge process for shared libraries.
572+
573+
The generated coverage report can be accessed at `build/coverage_report/index.html`.
574+
516575
### Performance profiling with perf
517576

518577
Profiling is a good way to get a precise idea of where time is being spent in

0 commit comments

Comments
 (0)