Having searched the Internet several times to find out how to get coverage
information out of clang, I ended up feeling rather confused. I’m sure I’m
not the only one. The reason for the confusion is fairly simple; clang
supports two different coverage tools, one of which uses a tool with a name
that used to be used by the other one!
About half of the posts seem to indicate that the right way to get coverage
information is to use the --coverage argument to clang:
1 2 3 4 5 6 | |
This appears to produce (approximately) GCOV format data which can then be
used with the gcov command, noting that this is really LLVM’s gcov, not
GNU gcov, though it appears to be designed to be broadly compatible with the
latter. Older versions of LLVM apparently used to call this tool llvm-cov
rather than replacing gcov with it, but that name is now used for a newer,
separate tool.
The rest of the posts, including some on the LLVM site, instead recommend using
the -fprofile-instr-generate and -fcoverage-mapping options:
1 2 3 4 5 6 | |
Instead of outputting GCOV data, this generates a file default.profraw,
which can be used with llvm-profdata and llvm-cov
The way to use this file is to do something like
1 2 | |
In case you were wondering: you must pass the raw profile data through
llvm-profdata. It isn’t in the format llvm-cov wants, and apparently the
“merge” operation does more than just merging.
Also, you can change the name of the output file, either by setting the
LLVM_PROFILE_FILE environment variable, or by compiling your code with
-fprofile-instr-generate=<filename>. This is mentioned in the help output
from the clang command, but doesn’t seem to be anywhere in the clang
documentation itself.
In both cases, you need to pass the coverage options to the clang or
clang++ driver when you are linking as well as when you are compiling.
This will cause clang to link with any libraries required by the profiling
system. You do not need to explicitly link with a profiling library when
using clang.
One final remark: on Mac OS X, gcov will likely be in your path, but
llvm-profdata and llvm-cov will not–instead, you can access them via
Xcode’s xcrun tool.