调试构建失败的确切方法取决于问题的性质以及bug
发起的系统区域。标准调试方法,例如与上一个已知工作版本的比较,检查更改以及重复识别导致问题的步骤,对Yocto
项目是有效的,就像它们用于任何其他系统一样。尽管不可能详细说明每个可能的潜在bug
,但这里提供了一些有助于在各种情况下进行调试的一般提示。
从失败的任务中查看日志
可以在${WORKDIR}/temp/log.do_taskname
文件中找到任务的日志。例如,用于x86
机器(qemux86
)的QEMU
最小镜像的do_compile
任务的日志可能位于tmp/work/qemux86-poky-linux/core-image-minimal/1.0-r0/temp/log.do_compile
中。要查看为生成日志而运行的BitBake
命令,请在相同目录中的查看相应的do_taskname
文件。
log.do_taskname
和run.do_taskname
实际上是log.do_taskname.pid
和log.run_taskname.pid
的符号链接,其中pid
就是task
的PID
号。符号链接始终指向最近运行任务相对应的文件。
查看变量值
BitBake
的-e
选项用于在解析后显示变量值。下面的命令在所有配置文件被解析后显示变量值:
$ bitbake -e
以下命令在解析特定食谱后显示变量值,包括配置中的变量:
$ bitbake -e recipename
用oe-pkgdata-util
查看包信息
可以使用oe-pkgdata-util
命令行实用程序来查询 PKGDATA_DIR
和显示各种与包相关的信息。以下是一些可用的 oe-pkgdata-util
子命令:
oe-pkgdata-util list-pkgs [pattern]
:列出已构建的所有包,可选择将匹配限制为匹配的包pattern
。oe-pkgdata-util list-pkg-files package ...
:列出给定包中包含的文件和目录。oe-pkgdata-util find-path path ...
:列出包含给定路径的包的名称。例如,以下内容告诉我们/usr/share/man/man1/make.1
包含在make-doc
包中:
$ oe-pkgdata-util find-path /usr/share/man/man1/make.1
make-doc: /usr/share/man/man1/make.1
oe-pkgdata-util lookup-recipe package ...
:列出生成给定包的食谱的名称。
有关oe-pkgdata-util
命令的更多信息,请使用帮助工具:
$ oe-pkgdata-util ‐‐help
$ oe-pkgdata-util subcommand --help
查看食谱和任务之间的依赖关系
有时很难理解为什么BitBake
想要在你指定的食谱之前建立其他食谱。依赖关系信息可以帮助你了解食谱的构建原因。
要为食谱生成依赖关系信息,请运行以下命令:
$ bitbake -g recipename
此命令将以下文件写入当前目录:
pn-buildlist
:构建recipename
时包含的食谱/目标列表task-depends.dot
:显示任务之间依赖关系的图表。
你也可以使用一个不同的方法来查看依赖关系:
$ bitbake -g -u taskexp recipename
使共享状态无效以强制运行任务
OpenEmbedded
构建系统使用 校验 和和 共享状态 缓存来避免不必要的重建任务。总的来说,这种方案被称为“共享状态代码”。
与所有方案一样,这个方案有一些缺点。可以对代码进行隐式更改,校验和计算不会考虑这些更改。这些隐式更改会影响任务的输出,但不会触发共享状态代码来重建食谱。
识别隐式更改时,可以轻松地采取措施使缓存无效并强制运行任务。可以采取的步骤就像在源代码中更改函数的注释一样简单。例如,要使程序包共享状态文件无效,更改do_package
其调用的某个函数的注释语句 或注释。即使更改纯粹是装饰性的,它也会导致重新计算校验和,并强制构建系统再次运行任务。
运行特定任务
任何给定的食谱都包含一组任务。在大多数情况下,标准BitBake
的行为是:do_fetch, do_unpack, do_patch, do_configure, do_compile, do_install, do_package, do_package_write_*
, 和 do_build
. 默认任务是do_build
和它首先依赖于build
的任何任务。有些任务,比如do_devshell
,不是默认构建链的一部分。如果希望运行不属于默认构建链的任务,可以使用BitBake
中的-c
选项。举个例子:
$ bitbake matchbox-desktop -c devshell
如果想强制重新运行一个最新的任务(例如,因为对菜谱的WORKDIR
进行了手工修改),那么可以使用-f
选项。
下面的例子展示了一种使用-f
选项的方法:
$ bitbake matchbox-desktop
.
.
对工作目录中的源代码进行一些更改
.
.
$ bitbake matchbox-desktop -c compile -f
$ bitbake matchbox-desktop
此序列首先构建然后重新编译 matchbox-desktop
。最后一个命令在编译后重新运行所有任务(基本上是打包任务)。BitBake
认识到该do_compile
任务已重新运行,因此理解其他任务也需要再次运行。
没有依赖的构建
要构建特定食谱,可以使用以下命令格式:
$ bitbake -b somepath/somerecipe.bb
此命令不检查依赖项。因此,只有在知道已满足现有依赖项时才应使用它。
使用devshell
在调试某些命令甚至只是编辑包时,devshell
可能是一个有用的工具。当调用devshell
时,将为指定的目标运行到do_patch
之前和包括do_patch
在内的所有任务。然后,打开一个新终端,并将放置在源目录${S}
中。在新的终端中,仍然定义了所有与构建相关的OpenEmbedded
环境变量,因此可以使用configure
和make
等命令。这些命令执行起来就像OpenEmbedded
构建系统正在执行它们一样。因此,在调试构建或准备与OpenEmbedded
构建系统一起使用的软件时,这种方法非常有用。
下面是一个在名为matchbox-desktop
的目标上使用devshell
的例子:
$ bitbake matchbox-desktop -c devshell
该命令在OpenEmbedded
的构建环境中生成一个带有shell
提示符的终端。OE_TERMINAL
变量控制打开的shell
类型。
对于衍生终端,发生以下情况:
PATH
变量包括交叉工具链。pkgconfig
变量找到正确的.pc
文件。configure
命令查找Yocto
项目站点文件以及任何其他必要的文件。
在这个环境中,可以运行configure
或compile
命令,就好像它们是由OpenEmbedded
构建系统本身运行的一样。如前所述,工作目录也会自动更改为源目录。
值得记住的是,在使用devshell
时,需要使用完整的编译器名称,比如arm-poky-linux-gnuea -gcc
,而不是仅仅使用gcc
。这同样适用于其他应用程序,如binutils、libtool
等。BitBake
设置了环境变量,比如CC
来帮助应用程序,比如make
来找到正确的工具。
使用目标板上的GDB
进行调试
执行以下操作:
- 确保
GDB
在目标上。可以通过将“gdb”
添加到IMAGE_INSTALL
:
IMAGE_INSTALL_append = " gdb"
- 或者,可以将
“tools-debug”
添加到IMAGE_FEATURES
:
IMAGE_FEATURES_append = " tools-debug"
- 确保存在调试符号。可以通过安装
-dbg
来确保这些符号存在:
IMAGE_INSTALL_append = " packagename-dbg"
- 或者,可以执行以下操作来包含所有调试符号:
IMAGE_FEATURES_append = " dbg-pkgs"