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 文件后,我直接搜索那个库的名字,发现两条依赖路径指向了不同的版本。嗯,冲突的根源一下子就找到了。
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 覆盖了,而不是追加。这就是典型的覆盖问题。
-g 看结构,-s 看版本,-e 看细节。缺一不可。
2.4 知识体系图
下面这张图总结了三个工具的关系和使用场景:
你看,这三个工具各有侧重,但组合起来就是一套完整的诊断流程。先看依赖结构,再确认版本,最后查环境变量细节。我每次遇到冲突,都是按这个顺序来排查的。
-g 和 -s,忽略了 -e,结果折腾了半天才发现是某个 .bbappend 文件把变量覆盖了。所以,三个工具一个都不能少。
好了,这一章的内容就到这里。记住这三个命令,下次遇到依赖冲突,你就有章可循了。