如何合并的gcda文件的多个版本?

问题描述 投票:2回答:1

我使用的gcov我的应用程序获取覆盖信息。不过,也有我的应用程序3个实例同时运行创建3个版本的“gcda”文件。有没有一种方法来合并不同版本的同一个“gcda”的文件在我的覆盖率信息文件。

我想借此覆盖信息仅作为一个实例。

c++ gcov lcov
1个回答
0
投票

我刚才一直在寻找到同样的问题,这里是我发现了什么。 TL; DR是有可能,在最好的情况下,由刚刚被小心编译顺序,并在使用gcov-tool merge命令最普通的(复杂)的方式,但这不是直的开箱即用,它需要一些专门的设置为了得到它的工作。

在我的例子,我有一个库文件,lib.cpp,有两个功能:

#include <iostream>

void five(int n) {
        if (n > 5) {
                std::cout << n << " is greater than five" << std::endl;
        } else {
                std::cout << n << " is not greater than five" << std::endl;
        }
}

void ten(int n) {
        if (n > 10) {
                std::cout << n << " is greater than ten" << std::endl;
        } else {
                std::cout << n << " is not greater than ten" << std::endl;
        }
}

然后我有两个程序,每个程序的调用它们的功能之一,five.cpp

#include <iostream>
#include "lib.hpp"

int main(int argc, char *argv[]) {
        if (argc != 2) {
                std::cerr << "usage: " << argv[0] << " <n>" << std::endl;
                return 2;
        }

        int n = std::stoi(argv[1]);
        five(n);
        return 0;
}

ten.cpp

#include <iostream>
#include "lib.hpp"

int main(int argc, char *argv[]) {
        if (argc != 2) {
                std::cerr << "usage: " << argv[0] << " <n>" << std::endl;
                return 2;
        }

        int n = std::stoi(argv[1]);
        ten(n);
        return 0;
}

假设代码位于一个/tmp/merge-gcov目录。

捕捉覆盖

启用覆盖捕获能像做

g++ -O0 --coverage -o five five.cpp lib.cpp

这将创造lib.gcnofive.gcno文件。当正在运行的程序five它会创建/tmp/merge-gcov/lib.gcda/tmp/merge-gcov/five.gcda。请注意,那些gcda路径被硬编码到二进制(但以后可以操纵,更多关于这一点)。

./five 1
./five 12       # Results from multiple runs will accumulate in gcda files
mkdir report
gcovr -r . --html --html-details --output report/report.html
firefox report/report.html 

矛盾多

到现在为止还挺好。但是,如果我们现在还编译ten程序以同样的方式

g++ -O0 --coverage -o ten ten.cpp lib.cpp

然后它会创建一个lib.gcno然后将其比新和不同于lib.gcno与编译five。这意味着只要fiveten是其他运行后它会检测到lib.gcda文件没有对应的预期(gcno来源)和复位文件内容,从而丢弃任何积累以前的内容。

这可以通过单独编译lib.cpp文件第一,例如能够避免

g++ -O0 --coverage -c lib.cpp 
g++ -O0 --coverage -o five lib.o five.cpp
g++ -O0 --coverage -o ten lib.o ten.cpp

现在无论fiveten将共享相同的lib.gcno,他们都将积累lib.gcda

所以,如果你是细心,所有的共享代码链接的二进制文件的编译前只有一次,你应该是好去累加从多个二进制文件覆盖效果。

的共享码不同的编译

但是,如果我们想要的东西,以不同的编译库?也许我们要编译一个版本的调试代码禁用一个与它启用了验证代码工作在两种情况下。然后前面的解决方案不起作用,而是战略是把文件每个二进制到它自己的目录,然后再合并这些目录。

g++ -O0 --coverage -c lib.cpp -DENABLE_DEBUG
g++ -O0 --coverage -o five lib.o five.cpp
mkdir gcov-five
mv *.gcno gcov-five/.

请注意,我说的gcda路径较早前硬编码?您可以只住在一起,运行每个二进制文件,然后移动*.gcda文件后记。或者你也可以设置环境变量,以使程序使用不同的目录。 GCOV_PREFIX_STRIP将从全路径的开始砍目录,例如GCOV_PREFIX_STRIP=1/tmp/merge-gcov/lib.gcda成为merge-gcov/lib.gcda。该GCOV_PREFIX变量将被放在路径的前面。

export GCOV_PREFIX=/tmp/merge-gcov/gcov-five
export GCOV_PREFIX_STRIP=2
# Gives /tmp/merge-gcov/gcov-five/lib.gcda
./five 1
./five 12

# Repeat for ten
g++ -O0 --coverage -c lib.cpp -DDISABLE_DEBUG
g++ -O0 --coverage -o ten lib.o ten.cpp
mkdir gcov-ten
mv *.gcno gcov-ten/.
export GCOV_PREFIX=/tmp/merge-gcov/gcov-ten
./ten 1
./ten 12

# Combine 
gcov-tool merge --outdir merged gcov-five gcov-ten
© www.soinside.com 2019 - 2024. All rights reserved.