************ 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将相对于构建目录写入。