34 使用 buildhistory 维护构建输出质量
许多因素都会影响构建质量。例如,将配方升级为使用新版上游软件包,或试用 新的配置选项,都可能产生直到后来才察觉的细微变化。假设配方改用了新版上游 软件包,而新版本增加了对另一个库的可选依赖,并自动检测该库。如果软件构建 时这个库已经构建完成,软件就会链接它,并将库随新软件一起带入镜像,即使你 并不希望包含该库。
buildhistory 类有助于维护构建输出质量,可突出显示意外 且可能不需要的输出变化。启用构建历史后,它记录各软件包和镜像的内容信息, 并提交到本地 Git 仓库,供你检查。
本节其余部分介绍:
34 启用和禁用构建历史
构建历史默认禁用。要启用它,在 build/conf/local.conf 等 configuration file 中添加以下 INHERIT 语句,并将 BUILDHISTORY_COMMIT 设为 "1":
INHERIT += "buildhistory"
BUILDHISTORY_COMMIT = "1"
按上述方式启用后,OpenEmbedded 构建系统会收集构建输出信息,并以单个提交 写入本地 Git 仓库。
备注
启用构建历史会略微增加构建时间,尤其是镜像构建时间,也会增加构建期间 的磁盘占用。
从 configuration file 中移除上述语句即可禁用构建历史。
34 理解构建历史的内容
构建历史信息保存在 Build Directory 的
${TOPDIR}/buildhistory 中,其位置由
BUILDHISTORY_DIR 定义。以下为简化的目录示例:
顶层的 metadata-revs 文件列出生成此次构建时各启用层所在仓库的修订版本。
其他数据分别存放在 packages、images 和 sdk 目录中,内容如下。
34 构建历史中的软件包信息
每个软件包的历史都包含文本文件,以名称和值的形式记录信息。例如,
buildhistory/packages/i586-poky-linux/busybox/busybox/latest 包含:
PV = 1.22.1
PR = r32
RPROVIDES =
RDEPENDS = glibc (>= 2.20) update-alternatives-opkg
RRECOMMENDS = busybox-syslog busybox-udhcpc update-rc.d
PKGSIZE = 540168
FILES = /usr/bin/* /usr/sbin/* /usr/lib/busybox/* /usr/lib/lib*.so.* \
/etc /com /var /bin/* /sbin/* /lib/*.so.* /lib/udev/rules.d \
/usr/lib/udev/rules.d /usr/share/busybox /usr/lib/busybox/* \
/usr/share/pixmaps /usr/share/applications /usr/share/idl \
/usr/share/omf /usr/share/sounds /usr/lib/bonobo/servers
FILELIST = /bin/busybox /bin/busybox.nosuid /bin/busybox.suid /bin/sh \
/etc/busybox.links.nosuid /etc/busybox.links.suid
大多数名称和值对应生成软件包时使用的变量。例外是 FILELIST,表示软件包
实际文件列表;以及 PKGSIZE,表示包中文件总大小,单位为字节。
另有对应软件包来源配方的文件,例如
buildhistory/packages/i586-poky-linux/busybox/latest:
PV = 1.22.1
PR = r32
DEPENDS = initscripts kern-tools-native update-rc.d-native \
virtual/i586-poky-linux-compilerlibs virtual/i586-poky-linux-gcc \
virtual/libc virtual/update-alternatives
PACKAGES = busybox-ptest busybox-httpd busybox-udhcpd busybox-udhcpc \
busybox-syslog busybox-mdev busybox-hwclock busybox-dbg \
busybox-staticdev busybox-dev busybox-doc busybox-locale busybox
对于从 Git 等版本控制系统获取的配方,还会有文件列出配方指定的源码修订版本
以及构建实际使用的版本。SRCREV 设为 ${AUTOREV} 时,两者
可能不同。以下以
buildhistory/packages/qemux86-poky-linux/linux-yocto/latest_srcrev 为例:
# SRCREV_machine = "38cd560d5022ed2dbd1ab0dca9642e47c98a0aa1"
SRCREV_machine = "38cd560d5022ed2dbd1ab0dca9642e47c98a0aa1"
# SRCREV_meta = "a227f20eff056e511d504b2e490f3774ab260d6f"
SRCREV_meta ="a227f20eff056e511d504b2e490f3774ab260d6f"
使用 buildhistory-collect-srcrevs 命令的 -a 选项,可以收集构建历史
保存的 SRCREV 值,并以适合全局配置的格式输出,例如用于发行版包含
configuration file,将浮动的 AUTOREV 固定为一组修订版本。
示例输出如下:
$ buildhistory-collect-srcrevs -a
# all-poky-linux
SRCREV:pn-ca-certificates = "07de54fdcc5806bde549e1edf60738c6bccf50e8"
SRCREV:pn-update-rc.d = "8636cf478d426b568c1be11dbd9346f67e03adac"
# core2-64-poky-linux
SRCREV:pn-binutils = "87d4632d36323091e731eb07b8aa65f90293da66"
SRCREV:pn-btrfs-tools = "8ad326b2f28c044cb6ed9016d7c3285e23b673c8"
SRCREV_bzip2-tests:pn-bzip2 = "f9061c030a25de5b6829e1abf373057309c734c0"
SRCREV:pn-e2fsprogs = "02540dedd3ddc52c6ae8aaa8a95ce75c3f8be1c0"
SRCREV:pn-file = "504206e53a89fd6eed71aeaf878aa3512418eab1"
SRCREV_glibc:pn-glibc = "24962427071fa532c3c48c918e9d64d719cc8a6c"
SRCREV:pn-gnome-desktop-testing = "e346cd4ed2e2102c9b195b614f3c642d23f5f6e7"
SRCREV:pn-init-system-helpers = "dbd9197569c0935029acd5c9b02b84c68fd937ee"
SRCREV:pn-kmod = "b6ecfc916a17eab8f93be5b09f4e4f845aabd3d1"
SRCREV:pn-libnsl2 = "82245c0c58add79a8e34ab0917358217a70e5100"
SRCREV:pn-libseccomp = "57357d2741a3b3d3e8425889a6b79a130e0fa2f3"
SRCREV:pn-libxcrypt = "50cf2b6dd4fdf04309445f2eec8de7051d953abf"
SRCREV:pn-ncurses = "51d0fd9cc3edb975f04224f29f777f8f448e8ced"
SRCREV:pn-procps = "19a508ea121c0c4ac6d0224575a036de745eaaf8"
SRCREV:pn-psmisc = "5fab6b7ab385080f1db725d6803136ec1841a15f"
SRCREV:pn-ptest-runner = "bcb82804daa8f725b6add259dcef2067e61a75aa"
SRCREV:pn-shared-mime-info = "18e558fa1c8b90b86757ade09a4ba4d6a6cf8f70"
SRCREV:pn-zstd = "e47e674cd09583ff0503f0f6defd6d23d8b718d3"
# qemux86_64-poky-linux
SRCREV_machine:pn-linux-yocto = "20301aeb1a64164b72bc72af58802b315e025c9c"
SRCREV_meta:pn-linux-yocto = "2d38a472b21ae343707c8bd64ac68a9eaca066a0"
# x86_64-linux
SRCREV:pn-binutils-cross-x86_64 = "87d4632d36323091e731eb07b8aa65f90293da66"
SRCREV_glibc:pn-cross-localedef-native = "24962427071fa532c3c48c918e9d64d719cc8a6c"
SRCREV_localedef:pn-cross-localedef-native = "794da69788cbf9bf57b59a852f9f11307663fa87"
SRCREV:pn-debianutils-native = "de14223e5bffe15e374a441302c528ffc1cbed57"
SRCREV:pn-libmodulemd-native = "ee80309bc766d781a144e6879419b29f444d94eb"
SRCREV:pn-virglrenderer-native = "363915595e05fb252e70d6514be2f0c0b5ca312b"
SRCREV:pn-zstd-native = "e47e674cd09583ff0503f0f6defd6d23d8b718d3"
34 构建历史中的镜像信息
每个镜像生成以下文件:
image-files:保存根文件系统中特定文件的目录,由 BUILDHISTORY_IMAGE_FILES 指定。build-id.txt:易于阅读的构建配置和元数据源码修订信息,包含 BitBake 输出的完整构建头部。*.dot:与graphviz兼容的镜像依赖图。files-in-image.txt:镜像文件列表,包含权限、所有者、组、大小及符号 链接信息。image-info.txt:以名称和值的形式记录镜像信息的文本文件,示例见下文。installed-package-names.txt:仅包含名称的已安装软件包列表。installed-package-sizes.txt:按大小排序的已安装软件包列表。installed-packages.txt:包含完整软件包文件名的已安装软件包列表。
备注
即使最终镜像禁用了包管理,仍然可以收集并生成已安装软件包信息。
image-info.txt 的示例如下:
DISTRO = poky
DISTRO_VERSION = 3.4+snapshot-a0245d7be08f3d24ea1875e9f8872aa6bbff93be
USER_CLASSES = buildstats
IMAGE_CLASSES = qemuboot qemuboot license_image
IMAGE_FEATURES = allow-empty-password empty-root-password allow-root-login post-install-logging
IMAGE_LINGUAS =
IMAGE_INSTALL = packagegroup-core-boot speex speexdsp
BAD_RECOMMENDATIONS =
NO_RECOMMENDATIONS =
PACKAGE_EXCLUDE =
ROOTFS_POSTPROCESS_COMMAND = ssh_allow_empty_password ssh_allow_root_login postinst_enable_logging rootfs_update_timestamp write_image_test_data empty_var_volatile sort_passwd rootfs_reproducible
IMAGE_POSTPROCESS_COMMAND = buildhistory_get_imageinfo
IMAGESIZE = 9265
除 IMAGESIZE 表示镜像中文件总大小(KB)外,其他名称和值都对应可能
影响镜像内容的变量。这些信息常有助于判断软件包或文件列表为何发生变化。
34 仅使用构建历史收集镜像信息
构建历史生成镜像信息及依赖图,可帮助理解某项内容为何进入镜像。如果只关心 这些信息,不需要特定软件包或 SDK 信息,可以在 configuration file 中添加以下内容,只写镜像信息而不保留历史:
INHERIT += "buildhistory"
BUILDHISTORY_COMMIT = "0"
BUILDHISTORY_FEATURES = "image"
此处将 BUILDHISTORY_FEATURES 设置为仅使用 image 功能。
34 构建历史中的 SDK 信息
构建历史对 SDK 内容收集的信息与镜像类似,例如执行
bitbake -c populate_sdk imagename 时收集的信息。生成可扩展 SDK 和标准
SDK 时,收集内容又有所不同。
SDK 会生成以下文件:
files-in-sdk.txt:SDK 文件列表,包含权限、所有者、组、大小和符号 链接信息,涵盖 SDK 的主机和目标两部分。sdk-info.txt:以名称和值的形式记录 SDK 信息的文本文件,见下方示例。sstate-task-sizes.txt:以名称和值的形式记录任务组大小,例如全部 do_populate_sysroot 任务的总大小。仅生成可扩展 SDK 时存在。sstate-package-sizes.txt:以名称和值的形式记录 SDK 共享状态软件包及 大小。仅生成可扩展 SDK 时存在。sdk-files:保存BUILDHISTORY_SDK_FILES指定且存在于输出中的文件 副本。BUILDHISTORY_SDK_FILES默认值专用于可扩展 SDK,但也可以修改 它以收集标准 SDK 中的指定文件。默认文件为 build/conf/local.conf、 build/conf/bblayers.conf、build/conf/auto.conf、
conf/locked-sigs.inc和conf/devtool.conf。对于可扩展 SDK,这些 文件会复制到sdk-files目录。host和target目录分别记录 SDK 中运行于主机和目标的部分, 各自包含以下信息:备注
生成可扩展 SDK 时,下列文件大多为空,因为它不像标准 SDK 那样从 软件包组装而来。
depends.dot:与graphviz兼容的 SDK 依赖图。installed-package-names.txt:仅包含名称的已安装软件包列表。installed-package-sizes.txt:按大小排序的已安装软件包列表。installed-packages.txt:包含完整软件包文件名的已安装软件包列表。
sdk-info.txt 的示例如下:
DISTRO = poky
DISTRO_VERSION = 1.3+snapshot-20130327
SDK_NAME = poky-glibc-i686-arm
SDK_VERSION = 1.3+snapshot
SDKMACHINE =
SDKIMAGE_FEATURES = dev-pkgs dbg-pkgs
BAD_RECOMMENDATIONS =
SDKSIZE = 352712
除 SDKSIZE 表示 SDK 中文件总大小(KB)外,其余名称和值对应可能影响
SDK 内容的变量。这些信息常有助于判断软件包或文件列表变化的原因。
34 检查构建历史信息
可以通过命令行或 Web 界面检查构建历史输出。
若 BUILDHISTORY_COMMIT = "1",可使用任意能查看仓库历史的 Git 命令检查变化,例如:
$ git log -p
不过,这种方式也会显示不重要的变化,例如软件包大小只变化几字节。
buildhistory-diff 命令行工具会查询 Git 仓库,仅以易读形式输出可能
重要的差异,例如:
$ bitbake-builds/layers/openembedded-core/scripts/buildhistory-diff . HEAD^
Changes to images/qemux86_64/glibc/core-image-minimal (files-in-image.txt):
/etc/anotherpkg.conf was added
/sbin/anotherpkg was added
* (installed-package-names.txt):
* anotherpkg was added
Changes to images/qemux86_64/glibc/core-image-minimal (installed-package-names.txt):
anotherpkg was added
packages/qemux86_64-poky-linux/v86d: PACKAGES: added "v86d-extras"
* PR changed from "r0" to "r1"
* PV changed from "0.1.10" to "0.1.12"
packages/qemux86_64-poky-linux/v86d/v86d: PKGSIZE changed from 110579 to 144381 (+30%)
* PR changed from "r0" to "r1"
* PV changed from "0.1.10" to "0.1.12"
备注
buildhistory-diff 需要 GitPython 软件包。请用 Pip3 安装:
$ pip3 install GitPython --user
也可以使用发行版包管理器安装 python3-git,例如 apt、dnf 或
zipper。
要通过 Web 界面查看构建历史变化,请遵循 此处
的 README 文件说明。
以下是界面截图示例: