使用gcov进行交叉编译,但GCOV_PREFIX和GCOV_PREFIX_STRIP被忽略。

12

我想使用GCOV进行代码覆盖率测试,但是测试将在另一台机器上运行。因此,在可执行文件中硬编码的路径到.gcda文件将无法工作。

为了更改默认目录,我可以使用GCOV_PREFIX和GCOV_PREFIX_STRIP环境变量,如这里所说。

这是我使用的命令:

$ export GCOV_PREFIX="/foo/bar"
$ export GCOV_PREFIX_STRIP="3"
$ gcc main.c -fprofile-arcs -ftest-coverage
$ strings a.out | grep gcda
/home/calmarius/blahblah/main.c.gcda

路径保持不变。 有人有这方面的经验吗?

1
当然,我的问题是:如何使这个工作? - Calmarius
2个回答

36

在运行代码时,环境变量会被考虑在内。

在运行测试之前,请将它们设置为目标计算机上的适当值,.gcda文件将生成在您想要的位置。


1
谢谢!有关该功能的更多信息可以在此处获取:https://gcc.gnu.org/ml/gcc-patches/2005-05/msg00324.html - eresonance

18

************ ARRRRGGGGGHHHHH ************

Please, please vote for Mat's answer.

当你运行代码时,环境变量会被考虑在内。

这句话很显然在关于如何重定位输出的所有文档中都没有提到过!

实际上,让我稍微扩展一下这个答案。

GCOV_PREFIX是一个运行时环境变量,与构建时间相对应,并确定gcov输出文件(*.gcda)写入的根目录。

GCOV_PREFIX_STRIP=X也是一个运行时变量,可以从对象文件中找到的路径(字符串XXXX.o)中剥离X个元素。

这意味着:

当您构建项目时,对象文件中嵌入的每个源文件负责每个对象文件的位置都带有完整路径。

所以,想象一下您正在编写一个可执行文件MyApp和一个库MyLib,它们位于以下目录结构中:

/MyProject 
 |-MyApp 
 |--MyLib

注意:MyLib是MyApp的子目录。

假设MyApp有2个源文件,MyLib有3个源文件。

在使用“-coverage”标志进行构建后,您将生成5个.gcno文件,每个对象文件对应一个文件。

嵌入在MyApp的.o文件中的是绝对路径**/MyProject/MyApp/**a_source_file.cpp。同样地,在MyLib的.o文件中嵌入的是路径**/MyProject/MyApp/MyLib/**another_source_file.cpp。

现在,假设您和我一样,将这些文件移动到具有与构建所在地不同的目录结构的完全不同的机器上。在我的情况下,目标机器实际上是完全不同的架构。我在该机器上部署到/some/deploy/path而不是/MyProject。

如果您只是运行应用程序,gcov数据将尝试为项目中的每个对象文件在/MyProject/MyApp和/MyProject/MyApp/MyLib中编写相应的.gcda文件,因为这是.o文件指示的路径,而MyApp和MyLib仅仅是打包在一起的.o文件集合,并具有其他修补函数指针等的魔法。

很可能,这些目录不存在,而且您可能没有以root身份运行(您是吗?),因此这些目录也不会被创建。所以...在部署位置/some/deploy/path中就看不到任何gcda文件。

这完全令人困惑,对吧!?????

这时就需要使用GCOV_PREFIX和GCOV_PREFIX_STRIP。

(啪!拳头打在额头上)您需要指示****运行时****.o文件中嵌入的路径实际上并不是您想要的路径。您希望“剥离”一些路径,并用部署目录替换它。

因此,通过设置GCOV_PREFIX=/some/deploy/path来设置部署目录,您希望剥离生成的.gcda路径中的/MyProject,因此您将GCOV_PREFIX_STRIP=1。

设置了这两个环境变量后,运行您的应用程序,然后查看/some/deploy/path/MyApp和/some/deploy/path/MyApp/MyLib,神奇地出现了5个gcda文件,每个对象文件对应一个文件。

注意:如果进行源码建立,则问题会更加复杂。.o指向源文件,但是gcda将相对于构建目录写入。


如果GCOV_PREFIX_STRIP大于目录数会发生什么?它是否愚蠢到剥离文件名,还是直接将文件名连接到GCOV_PREFIX?我想象中的情况是,一个沮丧的我只想把它们放在/tmp中,设置strip=100000和prefix=/tmp/。 - Brydon Gibson
1
没什么头绪,但运行一下并找出答案并不难。这是一项非破坏性测试。 - SmittyBoy

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