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在整个覆盖率分析工具链中的位置,我画了一张图:

Lcov 在覆盖率分析工具链中的位置 源码 (.c/.cpp) 编译 GCC --coverage (插桩编译) 运行 运行程序 (生成 .gcda) 收集 lcov 命令 (生成 .info) 转换 genhtml 命令 (生成 HTML) 查看 HTML 报告 (浏览器打开) 分析 覆盖率分析 (找未覆盖代码) Gcov 负责步骤1-3(编译插桩 + 数据生成) Lcov 负责步骤4-5(数据收集 + 可视化) 开发者负责步骤6-7(分析报告,改进测试)

这张图清晰地展示了:Gcov是底层基础,Lcov是上层可视化工具。两者配合,才能发挥最大价值。

4.6 小结

这一章,我们聊了Lcov是什么、它和Gcov的关系、怎么安装、以及两个核心命令 lcov 和 genhtml 的用法。

记住几个关键点:

  • Lcov不替代Gcov,而是增强Gcov。
  • 工作流是:编译 → 运行 → lcov收集 → genhtml生成。
  • .info文件是中间格式,可以保留下来,方便后续重新生成报告。

我个人觉得,Lcov是覆盖率分析工具链里“性价比”最高的一个工具。学起来简单,用起来顺手,效果立竿见影。你想想看,几分钟就能从一堆数字变成漂亮的HTML报告,何乐而不为呢?

好了,这一章就到这里。下一章,我们会深入Lcov的高级用法,比如合并多个覆盖率数据、过滤目录、设置阈值等等。到时候见。


可可精品资料库