在更大的项目中使用gcov(静态库,...)

9

我正在处理一个较大的项目,它具有以下目录布局:

Source
 MyA
  aa.cpp
  ab.cpp
  ac.cpp
 MyB
  ba.cpp
  bb.cpp
  bc.cpp
 MyTest
  testaa.cpp
  testab.cpp
  testac.cpp
  testba.cpp
  testbb.cpp
  testbc.cpp
  main.cpp
Build
 MyA
  aa.o
  ab.o
  ac.o
  libMyA.a (static library)
 MyB
  ba.o
  bb.o
  bc.o
  libMyB.a (static library)
 MyTest
  testaa.o
  testab.o
  testac.o
  testba.o
  testbb.o
  testbc.o
  MyTest (executable)

在使用-fprofile-arcs -ftest-coverage编译后,我在Build/MyTest目录中执行MyTest应用程序。预期在Build目录中会有*.gcno和*.gcda文件。在MyTest目录中运行gcov后,会生成不同的*.gcov文件,但不幸的是,它们并不包括MyA和MyB中的所有内容,尽管这两个库中的每个函数都被调用。尝试了不同的选项,但以这种方式我无法创建有用的(意味着正确的)*.gcov文件。

如果我将每个cpp文件复制到一个目录中并重复这些步骤,则一切正常,并且覆盖分析完美。
3个回答

10
  1. 你必须将源文件指定为g++/gcc的绝对路径。不要使用相对路径,如".."或"foo/bar.cpp",否则会出现类似"geninfo: WARNING: no data found for XXXX"的错误。

  2. 不要在g++/gcc的命令行中包含任何头文件,否则会出现"stamp mismatch with graph file"错误。

因此,在具有多个目录的情况下,应该这样操作:

g++ --coverage -DDEBUG -g3 heyo.cpp /app/helper/blah.cpp /app/libfoo/foo.cpp -o program

./program

lcov --directory . --capture --output-file app.info

genhtml --output-directory cov_htmp app.info

或者,如果你已经在使用相对路径的Makefile中,可以方便地使用:

g++ --coverage -DDEBUG -g3 $(abspath heyo.cpp helper/blah.cpp ../foo/bar/baz.cpp) -o program

这在我的情况下完美地运作。非常感谢。我想我之前低估了 lcov - lllllllllllll

5
为了保持目录结构,您需要在每个源文件文件夹中运行gcov一次,但使用-o选项告诉gcov数据文件的位置。
我认为应该像这样:
gcov -o ../../Build/MyA *.cpp

我有一个与该项目类似的源文件结构,但是我让编译器将目标文件等倒入源文件夹中。然后我从根文件夹中多次运行 gcov,每次针对一个源文件,但我会指定该源文件的相对路径,并使用 -o 选项来指定相对文件夹,如下所示:

gcov -o Source/MyA Source/MyA/aa.cpp

我假设你也是从根目录调用gcc/g++,对吗?如果我只是在任何目录中使用-o选项,那么我的*.gov文件都包含大量的/EOF/,尽管所有路径都设置正确。可能我的主要问题是构建系统(qmake)从不同的位置调用编译器。 - azraiyl
@azraiyl:我正在使用scons构建项目,所以我不完全确定,但是我认为scons使用相对路径来引用源文件。 - quamrana

-2

如果您已经彻底地手动测试了您的产品或应用程序,并付出了很多努力。如果您的目标是使用lcov和gcov获得代码覆盖率报告,但不小心删除了gcno文件。您可以通过重新编译代码来重新生成gcno文件,但它将生成新的时间戳,并且gcov报告错误,显示“图形文件与时间戳不匹配”,并且不会生成任何代码覆盖率报告。这将导致您所有的测试工作都白费了。

仍然有一种快捷方式可以生成代码覆盖率报告。这只是一个解决方法,不能一直依赖它。建议在测试完成之前保留*.gcno文件。

记下您的gcc版本(gcc -v),并从其中一个镜像站点下载其源代码 例如 - ftp://gd.tuwien.ac.at/gnu/sourceware/gcc/releases/gcc-4.4.6/gcc-4.4.6.tar.bz2

在提取下载的文件后,gcc文件夹结构如下所示 gcc-4.4.6 gcc-4.4.6/gcc

如果您直接进入gcc-4.4.6/gcc并尝试从那里执行./configure和编译(make),则会遇到以下问题 build/genmodes -h > tmp-modes.h /bin/sh: build/genmodes: 没有那个文件或目录

解决方案是从gcc-4.4.6执行./configure和make,不会显示与genmodes相关的任何错误。这将编译包括gcc在内的所有模块。如果./configure显示任何错误,则可能需要安装gcc所需的mpfr和gmp模块。
转到gcc-4.4.6/gcc/gcov.c并注释下面的行,然后使用上述命令重新编译。
/*  if (tag != bbg_stamp)
    {
      fnotice (stderr, "%s:stamp mismatch with graph file\n", da_file_name);
      goto cleanup;
    }*/

编译后新的 gcov 二进制文件示例路径为 gcc-4.4.6/host-x86_64-unknown-linux-gnu/gcc/gcov

将此二进制文件放置在 /usr/bin 中,并使用以下命令重新生成代码覆盖率报告,如下例所示 lcov --capture --directory ./ --output-file coverage.info ; genhtml coverage.info --output-directory /var/www/html/coverage

现在您不应该再遇到“与图形文件的时间戳不匹配”的错误,而且您将正确获得代码覆盖率报告


1
有很多有用的信息,但并没有回答原始问题。 - brian beuning

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