在 `gcc` 11 上,如何在使用 `--coverage` 时更改 `.gcno` 文件的前缀,以便它们匹配 `gcov` 的预期?

On `gcc` 11, how to change the prefix of `.gcno` files when using `--coverage` so they match what `gcov` expects?

我正在为我的 C 项目添加代码覆盖率。我遵循的过程是这样的:

# compile a .c file, expecting two new files "a.out" and "main.gcno"
gcc --coverage main.c

# run executable to get coverage data, expecting to create a new "main.gcda" file
./a.out

# use `gcov` to get formatted reports
gcov main.c

当我在版本 10.3.0 上使用 gcc 时,这一切都按预期工作,没有问题。然而,当 gcc 与版本 11.1.0 一起使用时,main.gcnomain.gcda 文件都有不同的名称,这会中断流程,如下所述。

使用gcc --coverage main.c 生成两个文件,a.outa-main.gcno。然后 运行 将可执行文件与 ./a.out 结合创建一个新文件 a-main.gcda。注意覆盖率文件上的前缀 a-。当 运行 执行下一个命令 gcov main.c 时,出现以下错误:

main.gcno:cannot open notes file
main.gcda:cannot open data file, assuming not executed

因为它正在寻找文件 main.gcnomain.gcda,但找不到它们。

为什么 gcc 的新版本会那样做?我在网上阅读的所有内容都假定编译器的输出应该与 gcov 同步,而 运行 在同一源文件上。我在任何地方都找不到更改覆盖率文件的输出名称的方法。

如果有帮助,我还注意到 a- 前缀取决于输出名称。因此,如果指定了输出名称 (gcc --coverage main.c -o test),则覆盖文件将以该名称作为前缀(test-main.gcnotest-main.gcda)。

我也试过手动重命名文件以删除前缀,gcov 似乎对此很满意。问题是我正在尝试使该过程自动化,我想要一种比猜测编译器用于覆盖文件的输出名称更可靠的方法。

作为参考,我还在 11.1.0 版本上使用 gcov。我不清楚这是否与 gcc 是同一版本有关。

Why does the new version of gcc do that?

请参阅 release notes for GCC 11,特别是警告的第三个项目符号开始“辅助和转储输出文件的命名和位置已更改”。

Everything I read online assumes that the output of the compiler should be in sync with gcov when run on the same source file. I couldn't find anywhere a way to change the output name of coverage files.

如发行说明中所述,-dumpbase 选项就是您想要的。要删除任何前缀,请使用 -dumpbase ''

我不确定 gcov 是否应该更新,或者 gcc-11 更改是否应该不会影响覆盖文件。 编辑: 这是行为 as expected

另一种解决方案是分两步编译和 link:

gcc --coverage main.c -c
gcc --coverage main.o

这样覆盖率数据文件就不会获得前缀,gcov 会按预期找到它们。