Search code examples
c++code-coverageclang++llvm-clang

clang++ always generates empty profraw coverage reports


I'm trying to integrate coverage in C++ with clang 6 for the first time and have been following this guide.

I successfully compiled the binary, generated a .profraw file and generated a .profdata file as described in steps 1, 2 and 3a. But when I try to create a line-oriented coverage report as described in 3b, I receive the following message:

error: build/debug/dane: Failed to load coverage: No coverage data found

Upon checking the .profraw file, I found it was empty. I tried changing my code a bit and running again but the generated .profraw was always empty.

My main.cpp file:

#include <iostream>

int main(int argc, char **argv) {
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

My SConstruct file:


env = Environment(CXX='clang++', CXXFLAGS=['-Wall', '-g', '-O0'], LINKFLAGS=['-fprofile-instr-generate', '-fcoverage-mapping'])
env.Program(target='build/debug/dane', source=['src/main.cpp'])

Command line output:

➤ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
clang++ -o src/main.o -c -Wall -g -O0 src/main.cpp
clang++ -o build/debug/dane -fprofile-instr-generate -fcoverage-mapping src/main.o
scons: done building targets.
➤ build/debug/dane
Hello, World!
➤ llvm-profdata merge -sparse default.profraw -o default.profdata
➤ llvm-cov show build/debug/dane -instr-profile=default.profdata
error: build/debug/dane: Failed to load coverage: No coverage data found

I expected the default.profraw file to hold meaningful coverage results, and have no clue why it's empty.


Solution

  • Finally solved it. At first I gave the -fprofile-instr-generate -fcoverage-mapping flags as CXXFLAGS, but it didn't work, and so I understood that these were linker flags and moved them to the LINKFLAGS (which resulted in this frustrated post). Apparently, these flags need to appear both as compilation and linker flags in order for the whole thing to work. I also tried checking if you can distribute the flags between the compiler and the linker but that didn't succeed.