使用单独的构建目录在CMake中使用gcov

17

我在使用gcov时遇到了问题。编译和链接过程中没有出现错误,但是当我运行可执行文件时,没有生成任何覆盖率数据。

我正在使用CMake和一个单独的构建目录,在这个目录下通过以下方式向编译器和链接器传递标志:

add_definitions(--coverage)
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " --coverage")

可执行文件是否期望源代码位于特定位置? 我需要在我的CMakeLists.txt中添加什么才能让一切顺利进行?

此致敬礼, Bjoern

4个回答

17

CMake似乎将代码覆盖率(*.gcda, *.gcdo)文件和项目的目标文件放在一起。如果你的可执行文件名为"tester",那么这些文件会出现在以下路径中。

${CMAKE_BINARY_DIR}/CMakeFiles/tester.dir/

CMake对于gcov来说,文件名的命名方式并不是很兼容。例如,如果我有一个名为"mytestprog.cpp"的源文件,则会构建它。

mytestprog.cpp.o
mytestprog.cpp.gcda
mytestprog.cpp.gcdno

然而,gcov似乎期望

mytestprog.gcda
mytestprog.gcdno

我不太确定该怎么修复它。我尝试使用了 LCov,但是它“似乎”能够工作,但我不确定是否真的可以。


1
出于某些原因,您可以仅指定对象文件并通过传递虚假值作为源文件来获取配置文件信息。例如:gcov -o mytestprog.cpp.o x 将生成 mytestprog.cpp.gcov 文件。 - bcmpinc
@bcmpinc,它将无法检查您在该文件中使用的标头。 - jackyalcine

12

Delcypher 指出了问题。

解决方法1:你可以使用未记录的CMAKE_CXX_OUTPUT_EXTENSION_REPLACE开关,要求cmake将对象文件命名为main.o而不是main.cpp.o等。

cmake -DCMAKE_CXX_OUTPUT_EXTENSION_REPLACE=ON ...
解决方案 2:如果您不需要.gcov文件,可以从构建目录中调用lcov
lcov --capture --directory . --output-file coverage.info
genhtml coverage.info --output-directory out

你可以在 out 目录中以 HTML 格式找到覆盖率信息。


3

不确定你从何处得到了--coverage,但是以下是我在Linux上使用gcc和gcov获取覆盖率信息的参数:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS
    "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")

这里是 gcc --help --verbose 对这些选项的说明:

-ftest-coverage 创建 "gcov" 需要的数据文件

-fprofile-arcs 插入基于弧的程序分析代码


3
在使用Clang时,--coverage可以以更简洁的格式实现那两个参数的功能。 - jackyalcine
2
GCC支持--coverage。https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html - mloskot

1

你不需要将 --coverage 传递给链接器。--coverage 将会传递 -fprofile-arcs 和 -ftest-coverage 给编译器,以及 -lgcov 给链接器。

你确定它没有创建任何 gcdo 或 gcda 文件吗?你在哪里寻找这些文件?它应该将每个目标文件的 gcov 文件放置在与目标文件相同的目录中。在构建目录的顶部执行查找 .gcda 文件的命令。如果没有显示任何内容,则可能没有链接 gcov。运行以下命令以查看是否已链接:

nm name_of_binary | grep "gcov"

如果它正在被链接,那么 gcov 可能没有权限将文件写入您运行可执行文件的位置。如果有权限,那么我就束手无策了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接