gcovr 安装_让sonar带着你的C++玩转devops

本文介绍了如何在Sonar中设置和使用gcovr进行C++代码覆盖率分析。作者强调了gcovr的重要性,并分享了在Linux环境下配置gcov和生成覆盖率报告的详细步骤,包括修改编译选项、正确运行程序、生成gcov文件以及设置SonarQube以接收gcov报告。
摘要由CSDN通过智能技术生成

最近一周一直在搞sonar。

越来越喜欢这个东东,众所周知,sonar本来是Java写的,对C++的支持一直是有限的。

上一篇文章,说了怎么让sonarcloud去联动travis的C++工程。

但是光静态检查代码实在是太low了。

我想使用它的更高级的功能,那就是代码覆盖率,以及对cppunit报告的联动。

不得不说,这部分耗费了我一周的时间,谷歌上的资料也坑不少,sonar大部分都是Java的项目,C++的项目在github上的例子多数问题也很多。自己一步一个坑摸过来,确实也不容易。不过当一切完成的时候,感觉还是蛮有成就感的。

首先,要说明一下, sonarcloud只支持CFamily插件,额外的扩展插件是不支持的,默认情况下,如果你使用的是自己安装的sonar服务器,CFamily插件如果不是giuhub项目是要收费的。这里推荐你可以使用另一个免费的sonar代码检查插件替换之。

这个插件的地址是:SonarOpenCommunity/sonar-cxx​github.com

在强调一次,这个插件,不能与sonarcloud联动,只能安装于sonar服务器上,这个插件的好处是可以支持gcovr的xml报告提交,而且对cppunit更友好一些。最关键的它是免费的。

因为我的项目在travis上,所以这个东西不能用。

sonarcloud只支持4种格式的代码覆盖率报告。他们是gcov,llvm-gcov, Visual Studio Reports和Bullseye。

后三个需要单独安装工具,gcov是为了检测linux的源代码覆盖率而原生的。不需要安装任何其它的组件,一般linux都会默认安装。

对应CFamily的组件功能介绍,看这里。SonarCFamily Coverage Results Import​docs.sonarqube.org

我直接使用的是gcov生成报告,但是有几步之前的工作要做。

首先,你需要独立写一个make文件,无论是Cmake也好,或者mpc也好,甚至是直接自己写的make也罢,你需要独立一个makegov文件,不与你的程序编译混淆,为什么呢?因为gcov需要在g++编译里面扩展参数。这个参数会让你的程序性能下降和内存变大(因为加入了桩),所以gcov不适合压测环境和正常环境,所以独立的一个make gcov很重要。

在你的make gcov编译选项里添加:

-fprofile-arcs -ftest-coverage

这个选项是用来开启gcov报告的。

当你的程序编译完成的时候,你会发现你的.o(程序编译中间文件)的目录下,会对应每个.o多了一个.gcno文件。

如果你看到这个,说明第一步你已经成功了。

第二步,就是完整运行你的程序。

这里注意,不能使用kill -9 或者类似的命令终止程序,一定要让程序自然退出。如果强行终止程序的话,你的gcba文件是不会生成出来的。

这里要多说一句,如果我写的是一个服务器程序,怎么合理关闭呢,这里你需要增加对信号量的抓取,也就是说,你可以用killall XXX的方式关闭你的程序,这时候你的程序会收到一个signal。你处理它让你的程序合理的关闭即可。(优雅的关闭)

正常的关闭后,你会在你的.o文件夹上看到一些新的文件。这个文件是.gcba,注意,这个文件也是和你的.o一一对应的。

类似这样:

ConnectClient.o

ConnectClient.gcno

ConnectClient.gcda

当你看到这些,gcov实际就成功了大半。我的理解是,编译器生成gcno的文件是你的代码中所有桩的位置,gcba是程序实际执行到关闭后的,所有的桩被调用的次数记录。

剩下的,就是使用gcov指令生成对应的代码覆盖率报告了。gcov指令会合并gcno和gcba文件生成一个.gcov的文件报告。注意,这里也是和.o一一对应的。

这里要强调一点。

gcov指令,必须在你的程序运行目录运行,在此之外运行都会报找不到文件的错误。也就是说,如果比较合理的配置,你的.o会在一个专门的目录,你的cpp会在另一个专门的目录。那么你应该在你的程序运行目录上运行gcov,切记。

类似这样:

- gcov -r -o ./.obj ../*.cpp

这里后面-o 的路径,和最后源代码的路径,都必须是相对于你的可执行文件路径的相对路径。

那么你也许会问,如果我的代码会有一堆的子目录(一般比较大的项目,代码目录都是严格区分的,不会混在一起的,怎么办?)

那么你可以一一指定它们。

例如:

- gcov -r -o ./.obj ../*.cpp

- gcov -r -o ./.obj ../Common/*.cpp

- gcov -r -o ./.obj ../Console/*.cpp

- gcov -r -o ./.obj ../FileTest/*.cpp

- gcov -r -o ./.obj ../TinyXML/*.cpp

- gcov -r -o ./.obj ../PacketParse/*.cpp

- gcov -r -o ./.obj ../LogSystem/*.cpp

- gcov -r -o ./.obj ../Message/*.cpp

- gcov -r -o ./.obj ../Reactor/*.cpp

- gcov -r -o ./.obj ../Mail/*.cpp

这里要说明的是,我目前还没有找到直接遍历子目录一句话的方式。

我目前使用的是这种比较笨的方式,因为*.cpp只能支持本级别的文件夹,所以有子文件夹的话,要额外指定出来。

好了,生成了所有的gcov文件。我们就需要sonarcloud去接收我们的文件了。

怎么写呢?

sonar.cfamily.gcov.reportsPath=./Linux_Bin

这里注意,这个路径是你的gcov文件所在的路径。

这样,sonarcloud就可以接收你的代码覆盖率报告并展现出来了。

类似这样:Loading...​sonarcloud.io

你可以点击你的代码覆盖率,查看自己的代码详细覆盖的情况。

那些代码行在运行过程中,没有被执行到。

或许你会问,我写的是服务器程序,没法做到完整的全覆盖呀。

其实这只是一个借口,想做到肯定是可以做到的,那么下一讲,我来说说,怎么用cppunit来配合你的代码覆盖率检查。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值