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.