如何使用gcov从多个源文件覆盖代码?获得;有弧到入口块“;

如何使用gcov从多个源文件覆盖代码?获得;有弧到入口块“;,c,gcov,C,Gcov,我有一个有很多源文件的项目。然后将它们编译为.o对象,最后与main.o链接以生成main.exe。我正在使用gcc编译所有文件(source1.c,source2.c,main.c),使用--coverage-O0,为每个文件生成.o和.gcno。然后,我将所有内容链接在一起并调用main.exe,再次为每个对象文件生成.gcda文件 当我运行gcov source1.o source2.o main.o时,会收到一条警告?错误?对于每个函数两次: ./tests/source1.gcno:'

我有一个有很多源文件的项目。然后将它们编译为
.o
对象,最后与
main.o
链接以生成
main.exe
。我正在使用gcc编译所有文件(
source1.c
source2.c
main.c
),使用
--coverage-O0
,为每个文件生成
.o
.gcno
。然后,我将所有内容链接在一起并调用
main.exe
,再次为每个对象文件生成
.gcda
文件

当我运行
gcov source1.o source2.o main.o
时,会收到一条警告?错误?对于每个函数两次:

./tests/source1.gcno:'build' has arcs to entry block
./tests/source1.gcno:'build' has arcs from exit block
问题是,这会使终端充满这些消息,并且需要很长时间才能完成。我在SO中只能找到,所以我检查了gcc和gcov的版本:

$ gcc --version
gcc.exe (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gcov --version
gcov (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
然而,这个问题对我帮助不大。我用的是装有巧克力的MinGW-w64。我在互联网上也找不到任何使用带有多个源文件的
gcov
的示例,因此标题为

我不知道到底出了什么问题,因为我已经被这个问题困扰了一个星期了。我的项目确实运行并生成代码覆盖率,但成千上万的警告使我的CI消息变得不必要的长

此外,如果有人能更好地解释警告信息的含义,我将不胜感激

编辑:

我用来编译
main.c
的标志示例:

gcc -Wall -Werror --coverage -O0 -lgcov -I ./tests/include -I ./src -c ./tests/main.c -o ./tests/build/main.o
不,那样不行。它的工作原理如下:

  • 您可以使用
    --覆盖率
    
    
    • --coverage
      在程序语句中插入如下内容
      fprintf(,“我在这里”)
    • 这样的
      fprintf
      语句在每个入口/出口函数、每个
      if
      入口/出口、每个流入口/出口等上生成
  • 然后你执行你的程序。
    • 在程序执行期间,将执行
      fprintf
      语句
    • 将创建一个日志文件,其中包含来自整个可执行文件的“我在这里”信息
  • 然后程序终止
  • 然后对生成的日志文件执行
    gcov
我在互联网上也找不到任何使用gcov和多个源文件的例子

@从单个源文件编辑为三个源文件

示例:让我们看看一些源文件<代码> 1 .c<代码> >代码> 2 .c<代码> >代码> 3。

cat >1.c <<EOF
main() {
    func(0);
}
EOF

cat >2.c <<EOF
int func(int a) {
    if (a) {
        printf("Never here\n");
    }
    printf("Always here\n");
}
EOF

cat >3.c <<EOF
int func2(int b) {
    if (b == 1) {
        printf("func2\n");
    }
    printf("func2 no \n");
    return b + 1;
}
EOF

cat >Makefile <<EOF
CFLAGS=--coverage
a.out: 1.o 2.o 3.o
    $(CC) $(CFLAGS) $^

EOF
然后我们运行可执行文件:

将创建新文件:

$ ls
1.c  1.c.gcov  1.gcda  1.o  2.c  2.c.gcov  2.gcda  2.o  3.c  3.c.gcov  3.gcda  3.o  Makefile  a.out*
然后您可以对这些文件执行
gcov

您可以检查生成的
1.c.gcov
文件


对对象文件执行
gcov
没有意义
gcov
解析执行中的信息
-lgcov
是不需要的-
-coverage
是所需要的一切(
-coverage
本身就是
-lgcov

即使在我对对象文件执行
gcov
时,我仍然得到了覆盖结果。现在我改成了
.gcda
文件,我仍然得到了相同的结果。我还删除了
-lgcov
。我也没有发现您的示例非常有用,因为>“我在互联网上也找不到任何使用gcov和多个源文件的示例,因此标题为。”?您只需从多个源文件编译可执行文件,然后在生成的文件上运行gcov
我在互联网上也找不到任何使用gcov和多个源文件的示例
。。。。好啊gcov自动“查找”它的文件,因此如果您将对象文件提供给它,它将尝试在与对象文件相同的目录中搜索gcda文件。因此,如果您执行
gcov file.o
gcov将搜索
file.gcno
file.o.gcno
以及类似的。。。文件的数量无关紧要,只是gcov必须找到结果文件。
$ make
cc --coverage   -c -o 1.o 1.c
cc --coverage   -c -o 2.o 2.c
cc --coverage   -c -o 3.o 3.c
cc --coverage 1.o 2.o 3.o
$ ./a.out
Always here
$ ls
1.c  1.c.gcov  1.gcda  1.o  2.c  2.c.gcov  2.gcda  2.o  3.c  3.c.gcov  3.gcda  3.o  Makefile  a.out*
$ gcov *.gcno
File '1.c'
Lines executed:100.00% of 2
Creating '1.c.gcov'

File '2.c'
Lines executed:80.00% of 5
Creating '2.c.gcov'

File '3.c'
Lines executed:0.00% of 5
Creating '3.c.gcov'