4
mkdir -p /tmp/build &&
cd /tmp/build &&
mkdir -p /tmp/src &&
echo "int main(){return 0;}" > /tmp/src/prog.c &&
gcc --coverage -o prog /tmp/src/prog.c &&
./prog &&
gcovr -v -r .

将输出一个空报告。

Scanning directory . for gcda/gcno files...
Found 2 files (and will process 1)
Processing file: /tmp/build/prog.gcda
Running gcov: 'gcov /tmp/build/prog.gcda --branch-counts --branch-probabilities --preserve-paths --object-directory /tmp/build' in '/tmp/build'
Finding source file corresponding to a gcov data file
  currdir      /tmp/build
  gcov_fname   #tmp#src#prog.c.gcov
               ['        -', '    0', 'Source', '/tmp/src/prog.c\n']
  source_fname /tmp/build/prog.gcda
  root         /tmp/build
  fname        /tmp/src/prog.c
Parsing coverage data for file /tmp/src/prog.c
  Filtering coverage data for file /tmp/src/prog.c
Gathered coveraged data for 0 files
------------------------------------------------------------------------------
                           GCC Code Coverage Report
Directory: .
------------------------------------------------------------------------------
File                                       Lines    Exec  Cover   Missing
------------------------------------------------------------------------------
------------------------------------------------------------------------------
TOTAL                                          0       0    --%
------------------------------------------------------------------------------

但是,如果我手动运行

gcov /tmp/build/prog.gcda --branch-counts --branch-probabilities --preserve-paths --object-directory /tmp/build

我得到正确的结果

File '/tmp/src/prog.c'
Lines executed:100.00% of 1
No branches
No calls
Creating '#tmp#src#prog.c.gcov'

似乎gcovr没有从其他正确的gcov输出中提取覆盖范围。仅当源文件位于当前目录之外(与构建目录相同,与输出目录相同,与运行目录相同)并且gcc使用源文件的绝对路径调用 ics 时才会发生这种情况。

我怎样才能解决这个问题?

编辑

在上游 gcovr 中修复了相对路径,但看起来像绝对路径的错误。

请参阅https://github.com/gcovr/gcovr/issues/169

4

2 回答 2

5

我从您的代码中了解到,您完成了所有工作并运行了程序,但您仍然位于目标文件所在的构建目录中。

所以,你需要了解的是:

gcovr -v -r <path>

-r标志采用根目录,即源目录和对象目录所在的父目录。这样它就可以同时跟踪它们并生成覆盖数据以及您希望它生成的任何其他内容。
尝试这样做,它会工作。

您的理解:

编译后生成的.gcno文件只是该特定源文件的流程图类型的数据。
然后稍后当您执行程序时,.gcda会为每个源文件生成一个文件。该文件包含真实的覆盖率数据,但对于 gcovr,所有这三个文件都是必需的(.gcno、.gcda、sourceFile)

希望它有所帮助。:)

更新:
返回解决
方法您可以将覆盖数据位置作为纯 arg(无选项)提供,并将根指向您的源。

gcovr .../path/To/GCDA -r .../path/to/src/ [rest desired flags]

这肯定会解决你的问题。
为我工作,涵盖我的项目。

于 2017-05-17T12:12:00.080 回答
1

Gcovr 只为项目中的源文件生成报告。这旨在排除库标题等的覆盖范围。

问题是,您的项目中有哪些文件?这是由-r根路径决定的。

如果您在/tmp/build其中并且 root 是.aka/tmp/build并且源文件是/tmp/src/prog.c,那么该源文件显然在您的项目之外。在详细输出中,gcovr 将报告Filtering coverage data for file /tmp/src/prog.c.

如果您在/tmp/build其中并且 root 是..aka/tmp并且源文件是/tmp/src/prog.c,那么该源文件在项目中。

如果您在/tmp/build其中并且 root 是.aka/tmp/build并且源文件是../src/prog.c,那么 gcovr 似乎做了一些有问题的事情:它将文件名与当前目录连接并检查它。所以我们实际上看到了/tmp/build/../src/prog.c。就 gcovr 而言,这在您的项目中。似乎这种行为对于包含符号链接到项目中的代码是必要的。

您可以禁用此“是项目中的源吗?” 通过提供您自己的更好的过滤器进行过滤。例如,您可以要求 gcovr 仅报告以下来源的覆盖率/tmp/src

gcovr -r . -f /tmp/src
于 2018-01-09T22:54:08.693 回答