2、冲突诊断工具:bitbake -g、-s、-e 三板斧

依赖冲突这东西,光靠猜是猜不出来的。我刚开始用 Yocto 那会儿,遇到包冲突就头大,日志刷屏也看不懂。后来慢慢摸清了几个诊断工具,才发现——其实没那么玄乎。

今天我就把最常用的三个命令掰开揉碎讲给你听。它们分别是:bitbake -g、bitbake -s 和 bitbake -e。说白了,就是看依赖关系、看版本、看环境变量。

2.1 bitbake -g:生成依赖树,分析 dot 文件

先说说 bitbake -g。这个命令能生成一个依赖关系图,保存成 dot 文件。dot 文件是啥?就是 Graphviz 工具能读的文本格式,描述节点和连线。

我个人习惯这样用:

bitbake -g core-image-minimal

跑完之后,当前目录下会多出两个文件:pn-buildlist 和 recipe-depends.dot。前者是配方列表,后者是依赖关系的 dot 文件。

dot 文件长这样:

digraph depends {
    "busybox" -> "glibc"
    "glibc" -> "linux-libc-headers"
    "core-image-minimal" -> "busybox"
    "core-image-minimal" -> "base-files"
}

箭头方向表示「依赖谁」。比如 busybox -> glibc,意思是 busybox 依赖 glibc。

我在项目中遇到过一个问题:两个配方都提供了同一个库,但版本不同。用 -g 生成 dot 文件后,我直接搜索那个库的名字,发现两条依赖路径指向了不同的版本。嗯,冲突的根源一下子就找到了。

小技巧: 如果 dot 文件太大,可以用 grep 过滤。比如 grep "openssl" recipe-depends.dot,只看跟 openssl 相关的依赖。

你还可以把 dot 文件转成图片,用 Graphviz 的 dot 命令:

dot -Tpng recipe-depends.dot -o deps.png

不过说实话,项目大了之后,图片会乱成一团。我一般还是直接看文本,配合 grep 和 less 翻页。

2.2 bitbake -s:查看配方版本

依赖关系看清楚了,接下来要确认版本。这时候 bitbake -s 就派上用场了。

这个命令会列出所有配方及其版本号。用法很简单:

bitbake -s | grep openssl

输出大概是这样:

openssl                     :1.1.1k-r0
openssl-native              :1.1.1k-r0
openssl-conf                :1.1.1k-r0

左边是配方名,右边是版本号。注意看那个 -r0,那是修订版本号。如果同一个配方有多个版本,这里会全部列出来。

我曾经遇到过一个坑:两个不同的层都提供了 openssl,但版本不一样。用 bitbake -s 一看,发现一个层是 1.1.1k,另一个层是 1.1.1l。Yocto 默认选版本高的,但高版本跟某个老驱动不兼容。嗯,这就是典型的版本冲突。

注意: bitbake -s 只显示配方定义的版本,不保证最终构建时用的是这个版本。最终版本还要看 PREFERRED_VERSION 变量的设置。

我个人习惯把 bitbake -s 的输出重定向到文件,然后用 vim 或者 less 慢慢翻。毕竟配方多了,屏幕刷一下就过去了。

2.3 bitbake -e:展开环境变量

最后一个工具是 bitbake -e。这个命令能展开所有环境变量,包括配方里定义的、层里覆盖的、以及全局配置的。

用法:

bitbake -e openssl

输出会非常长,几百行甚至上千行。但别怕,我们只关心关键变量。

我常用的几个变量:

变量名 作用
PREFERRED_VERSION 指定优先使用的版本
DEPENDS 构建时依赖
RDEPENDS 运行时依赖
PROVIDES 配方提供的功能
RPROVIDES 运行时提供的功能

想看某个变量的值,可以配合 grep:

bitbake -e openssl | grep ^PREFERRED_VERSION

注意那个 ^,表示行首。不然 grep 会把注释和赋值语句都匹配出来,信息太杂。

我记得有一次,一个配方死活找不到依赖。用 bitbake -e 展开后,发现 DEPENDS 变量里少了一个库。再一看,是某个 .bbappend 文件把 DEPENDS 覆盖了,而不是追加。这就是典型的覆盖问题。

核心思路: 三个命令配合使用,基本能解决 90% 的依赖冲突问题。-g 看结构,-s 看版本,-e 看细节。缺一不可。

2.4 知识体系图

下面这张图总结了三个工具的关系和使用场景:

依赖冲突诊断三板斧 bitbake -g 生成依赖树 bitbake -s 查看配方版本 bitbake -e 展开环境变量 recipe-depends.dot 配方名 + 版本号 所有变量展开值 诊断依赖冲突 找到冲突根源 → 确定版本 → 修复依赖 三个工具配合使用,覆盖依赖冲突诊断全流程

你看,这三个工具各有侧重,但组合起来就是一套完整的诊断流程。先看依赖结构,再确认版本,最后查环境变量细节。我每次遇到冲突,都是按这个顺序来排查的。

避坑指南: 我曾经在排查时只用了 -g 和 -s,忽略了 -e,结果折腾了半天才发现是某个 .bbappend 文件把变量覆盖了。所以,三个工具一个都不能少。

好了,这一章的内容就到这里。记住这三个命令,下次遇到依赖冲突,你就有章可循了。