CTestCoverageCollectGCOV reports wrong information (and other issues with it)
gcov by default is called without extra options (ctest_coverage()
) or with only -b
(ctest_coverage_collect_gcov()
).
This is problematic because the .gcov files can get overwritten, which would make cdash report incorrect information, if:
a) There are two source files with the same name in different directories
b) A single header file is included from multiple .cpp files.
'a' can be fixed by using -p
, but this has historically been rejected because it generates very long file names which can reach the file system limits. gcov has -x
, though, which can also solve 'a' without the long file names issue.
'b' is actually only an issue because of the way ctest_coverage()
/ctest_coverage_collect_gcov()
run gcov. They execute it once per .gcda file, making it possible for a gcov invocation to overwrite a .gcov file generated by a previous invocation. gcov accepts multiple .gcda files as input, so it's possible to run gcov only once, avoiding the overwriting issue.
As long as gcov keeps being executed once per .gcda file the overwriting issue can be avoided by calling gcov with the -l
option. But -x
disables -l
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89959), so as long as gcov keeps being executed once per .gcda file the only way to get reliable data is to call gcov with -p -l
... which will generate extra long file names, risking reaching the file system limit.
As long as -p -l
is a requirement, the file names could be made shorter by using -s ${CTEST_SOURCE_DIRECTORY}
. Combining this with -r
would even greatly reduce the amount of data that needs to be uploaded to CDash. Unfortunatelly CDash seems to be doing some filtering itself, meaning that if -s ${CTEST_SOURCE_DIRECTORY}
is used CDash will not report any coverage at all (https://github.com/Kitware/CDash/issues/824).