4、Lcov入门:Lcov是什么、Lcov与Gcov的关系、Lcov安装、Lcov基本命令(lcov, genhtml)
各位同学,欢迎来到第四章。前面我们聊了Gcov,知道了它能生成.gcda和.gcno文件,也能直接看文本报告。但说实话,Gcov原生的输出格式,嗯……有点“原始”。你想想看,一个几千行的C文件,让你对着终端里密密麻麻的“#####”和数字去数覆盖率,眼睛不花才怪。
所以,这一章我们聊聊Lcov。它是什么?说白了,Lcov就是Gcov的“可视化外挂”。
4.1 Lcov是什么
Lcov,全称是“Linux Test Coverage”,是一个基于Gcov的图形化前端工具。它把Gcov生成的原始数据,转化成HTML页面。你可以在浏览器里点来点去,看哪些行被覆盖了,哪些分支没跑到。
我个人习惯,每次跑完测试,第一件事就是打开Lcov生成的HTML报告。为什么?因为直观。红色代表没覆盖,绿色代表覆盖了,一目了然。你不需要再去记那些Gcov的标记符号了。
核心价值: Lcov = Gcov数据 + 可视化HTML。它不替代Gcov,而是让Gcov的数据变得“可读”。
4.2 Lcov与Gcov的关系
很多新手会问:“我有了Gcov,为什么还要Lcov?” 这个问题问得好。
我打个比方:Gcov是“矿工”,负责从代码里挖出覆盖率数据。Lcov是“炼金师”,把矿石提炼成金条。两者缺一不可。
具体来说,它们的分工是这样的:
| 工具 | 职责 | 产出物 |
|---|---|---|
| Gcov | 编译插桩、运行时数据收集、生成原始报告 | .gcno, .gcda, .gcov 文件 |
| Lcov | 解析.gcda/.gcno,生成.info中间文件,再转成HTML | .info 文件, HTML报告 |
你看,Gcov负责“干活”,Lcov负责“展示”。没有Gcov,Lcov就是无米之炊。没有Lcov,Gcov的数据就像一堆散落的零件。
我曾经在一个嵌入式项目里,团队只用Gcov看文本报告。每次评审,大家对着屏幕数数字,效率极低。后来我引入了Lcov,把报告生成HTML挂到内网服务器上,大家点开就能看。嗯,从那以后,覆盖率评审再也没人抱怨了。
4.3 Lcov安装
安装Lcov很简单。它是个开源工具,主流Linux发行版都有包。
我个人建议用包管理器安装,省心。当然,你也可以从源码编译,但没必要折腾自己。
Ubuntu/Debian 系:
sudo apt-get install lcov
CentOS/RHEL/Fedora 系:
sudo yum install lcov # CentOS 7
sudo dnf install lcov # Fedora / CentOS 8+
macOS(通过Homebrew):
brew install lcov
安装完成后,验证一下:
lcov --version
genhtml --version
如果能看到版本号,说明安装成功。
小提示: 如果你在容器或CI环境里,记得先安装GCC和Gcov。Lcov依赖它们。我曾经在Docker里忘了装GCC,折腾了半天才发现是环境问题。
4.4 Lcov基本命令
Lcov的核心命令就两个:lcov 和 genhtml。一个负责收集数据,一个负责生成报告。
4.4.1 lcov 命令:收集覆盖率数据
lcov 命令的作用,是把Gcov生成的.gcda和.gcno文件,解析成一个统一的.info文件。这个.info文件,就是Lcov的“中间格式”。
基本用法:
lcov --capture --directory . --output-file coverage.info
解释一下参数:
--capture:告诉Lcov,我要开始收集数据了。--directory .:指定Gcov数据所在的目录。通常就是当前目录。--output-file coverage.info:指定输出的.info文件名。
运行后,你会得到一个coverage.info文件。你可以用文本编辑器打开看看,里面记录了每个源文件的覆盖率信息。
注意: 运行lcov命令前,确保你的程序已经运行过,生成了.gcda文件。否则Lcov会报错“找不到数据”。我刚开始用的时候,经常忘了先跑测试,结果Lcov报错,我还以为是工具坏了。
有时候,你不想统计某些目录(比如第三方库、测试代码本身)。可以用 --exclude 参数:
lcov --capture --directory . --output-file coverage.info \
--exclude '/usr/*' \
--exclude '*/test/*'
这样,Lcov就会跳过/usr/目录和所有test目录下的文件。
4.4.2 genhtml 命令:生成HTML报告
有了.info文件,下一步就是用 genhtml 生成HTML报告。
基本用法:
genhtml coverage.info --output-directory coverage_report
解释一下:
coverage.info:上一步生成的中间文件。--output-directory coverage_report:指定输出目录。Lcov会在这个目录下生成一堆HTML文件。
运行后,你会看到一个 coverage_report 目录。里面有个 index.html,用浏览器打开它。
你会看到什么?
- 一个总览页面,显示整体覆盖率百分比。
- 每个源文件的覆盖率详情,行覆盖、分支覆盖、函数覆盖都有。
- 点击文件名,可以看到源码,绿色高亮是覆盖的行,红色是未覆盖的行。
说实话,我第一次看到这个报告时,心里就一个想法:“这才叫覆盖率工具嘛!”
4.4.3 完整工作流示例
我们来走一遍完整的流程。假设你有一个简单的C程序 test.c:
// test.c
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main() {
int result = add(2, 3);
printf("Result: %d\n", result);
return 0;
}
步骤1:编译,加上覆盖率选项
gcc --coverage test.c -o test
步骤2:运行程序,生成.gcda文件
./test
步骤3:用lcov收集数据
lcov --capture --directory . --output-file coverage.info
步骤4:用genhtml生成报告
genhtml coverage.info --output-directory coverage_report
步骤5:打开报告
firefox coverage_report/index.html
就这么简单。五步走,你就能看到漂亮的HTML报告了。
避坑指南: 我曾经在步骤3时,发现生成的.info文件里覆盖率全是0%。排查了半天,发现是步骤2运行的程序路径不对,导致.gcda文件没生成在当前目录。记住:lcov的--directory参数,必须指向.gcda文件所在的目录。
4.5 本章知识体系
为了让你更直观地理解Lcov在整个覆盖率分析工具链中的位置,我画了一张图:
这张图清晰地展示了:Gcov是底层基础,Lcov是上层可视化工具。两者配合,才能发挥最大价值。
4.6 小结
这一章,我们聊了Lcov是什么、它和Gcov的关系、怎么安装、以及两个核心命令 lcov 和 genhtml 的用法。
记住几个关键点:
- Lcov不替代Gcov,而是增强Gcov。
- 工作流是:编译 → 运行 → lcov收集 → genhtml生成。
- .info文件是中间格式,可以保留下来,方便后续重新生成报告。
我个人觉得,Lcov是覆盖率分析工具链里“性价比”最高的一个工具。学起来简单,用起来顺手,效果立竿见影。你想想看,几分钟就能从一堆数字变成漂亮的HTML报告,何乐而不为呢?
好了,这一章就到这里。下一章,我们会深入Lcov的高级用法,比如合并多个覆盖率数据、过滤目录、设置阈值等等。到时候见。