7 任务

任务是 BitBake 的执行单元。配方(.bb 文件)通过任务完成软件的配置、 编译和打包。本章提供 OpenEmbedded 构建系统中各任务的参考说明。

要按字母顺序查看某个配方定义的任务,可以运行:

$ bitbake -c listtasks recipename
do_build                              Default task for a recipe - depends on all other normal tasks required to 'build' a recipe
do_checkuri                           Validates the SRC_URI value
do_clean                              Removes all output files for a target including ${WORKDIR}, sstate manifests and stamps
do_cleanall                           Removes all output files, shared state cache, and downloaded source files for a target
do_cleansstate                        Removes all output files and shared state cache for a target
do_compile                            Compiles the source in the compilation directory
...

此外,配方构建完成后,可以在其 ${WORKDIR}/temp/ 目录中 查看生成的任务信息,包括:

  • 每个任务的 run 文件,包含该任务执行的代码。

  • 每个任务对应的 log 文件,显示任务执行结果。

  • 一个 log.task_order 文件,显示该配方所有任务的执行顺序。

7 常规配方构建任务

以下各节介绍与配方构建有关的常规任务。有关任务和依赖关系的更多信息, 请参阅《BitBake 用户手册》的 “Tasks”和 “Dependencies”两节。

7.1.1 do_build

所有配方的默认任务,依赖构建配方所需的其他全部常规任务。

7.1.2 do_compile

编译源码。此任务运行时,当前工作目录为 ${B}。

此任务的默认行为是:如果找到 makefile(Makefile、makefile 或 GNUmakefile),则运行 oe_runmake 函数。 如果未找到,do_compile 任务不执行任何操作。

7.1.3 do_compile_ptest_base

编译正在构建的软件附带的运行时测试套件。

7.1.4 do_configure

通过启用或禁用软件的构建选项和配置选项来配置源码。 任务运行时,当前工作目录为 ${B}。

默认情况下,如果找到 makefile(Makefile、makefile 或 GNUmakefile),且 CLEANBROKEN 未设为“1”, 此任务运行 oe_runmake clean。 如果没有找到此类文件,或 CLEANBROKEN 设为“1”, do_configure 任务不执行任何操作。

7.1.5 do_configure_ptest_base

配置正在构建的软件附带的运行时测试套件。

7.1.6 do_deploy

写入将部署到 ${DEPLOY_DIR_IMAGE} 的输出文件。 任务运行时,当前工作目录为 ${B}。

实现此任务的配方应继承 deploy 类, 并将输出写入 ${DEPLOYDIR}, 注意不要与 ${DEPLOY_DIR} 混淆。 deploy 类将 do_deploy 设置为共享状态 (sstate)任务,使其可以通过共享状态加速。 共享状态机制负责将输出从 ${DEPLOYDIR} 复制到 ${DEPLOY_DIR_IMAGE}。

备注

不要直接将输出写入 ${DEPLOY_DIR_IMAGE},否则会导致共享状态机制失效。

默认情况下不会添加 do_deploy 任务,因此需要手动添加。 如果希望它在 do_compile 之后运行,可以这样添加:

addtask deploy after do_compile

将 do_deploy 添加到其他任务之后的方式相同。

备注

无需向 addtask 命令添加 before do_build,尽管添加也无害, 因为 base 类包含以下设置:

do_build[recrdeptask] += "do_deploy"

更多信息请参阅《BitBake 用户手册》的 “Dependencies”一节。

如果 do_deploy 任务重新执行,会删除此前的所有输出, 即先进行清理。

7.1.7 do_fetch

获取源码。此任务根据 SRC_URI 变量及其参数的前缀, 选择正确的 获取器 模块。

7.1.8 do_image

开始镜像生成过程。OpenEmbedded 构建系统运行 do_rootfs 任务后,再运行 do_image。 前者确定需要安装到镜像中的软件包,创建根文件系统并完成其后处理。

do_image 通过 IMAGE_PREPROCESS_COMMAND 对镜像进行预处理,并根据需要动态生成辅助的 do_image_* 任务。

有关创建镜像的更多信息,请参阅《Yocto Project 概览与概念手册》的 “生成镜像”一节。

7.1.9 do_image_complete

完成镜像生成过程。OpenEmbedded 构建系统运行 do_image 任务后,再运行 do_image_complete。 前者执行镜像预处理,并通过动态生成的 do_image_* 任务构建镜像。

do_image_complete 通过 IMAGE_POSTPROCESS_COMMAND 对镜像进行后处理。

有关创建镜像的更多信息,请参阅《Yocto Project 概览与概念手册》的 “生成镜像”一节。

7.1.10 do_install

将待打包文件复制到暂存区 ${D}。 此任务运行时,当前工作目录为编译目录 ${B}。 do_install 及其他直接或间接依赖已安装文件的任务, 例如 do_package、 do_package_write_* 和 do_rootfs,都在 fakeroot 下运行。

备注

安装文件时,注意不要将文件的所有者 ID 和组 ID 设成非预期值。 某些复制方式,尤其是递归使用 cp 命令,可能保留原文件的 UID 和/或 GID,这通常不是所需的行为。 host-user-contaminated 质量检查会查找所有权可能不正确的文件。

安全的文件安装方式包括:

  • install 工具,这是首选方式。

  • 带 --no-preserve=ownership 选项的 cp 命令。

  • 带 --no-same-owner 选项的 tar 命令。 示例见 OpenEmbedded-Core (OE-Core) 的 meta/classes-recipe 子目录中的 bin_package.bbclass 文件。

7.1.11 do_install_ptest_base

将运行时测试套件文件从编译目录复制到暂存区。

7.1.12 do_package

分析暂存区 ${D} 的内容, 根据可用的软件包和文件将其拆分成子集。 此任务使用 PACKAGES 和 FILES 变量。

do_package 与 do_packagedata 还共同保存 一些重要的软件包元数据。更多信息请参阅 PKGDESTWORK 变量, 以及《Yocto Project 概览与概念手册》的 “自动添加运行时依赖”一节。

7.1.13 do_package_qa

对打包文件运行质量检查。有关这些检查的更多信息, 请参阅 质量检查错误和警告消息。

7.1.14 do_package_write_deb

创建 Debian 软件包(*.deb 文件),并将其放入软件包源区域的 ${DEPLOY_DIR_DEB} 目录。 更多信息请参阅《Yocto Project 概览与概念手册》的 “软件包源”一节。

7.1.15 do_package_write_ipk

创建 IPK 软件包(*.ipk 文件),并将其放入软件包源区域的 ${DEPLOY_DIR_IPK} 目录。 更多信息请参阅《Yocto Project 概览与概念手册》的 “软件包源”一节。

7.1.16 do_package_write_rpm

创建 RPM 软件包(*.rpm 文件),并将其放入软件包源区域的 ${DEPLOY_DIR_RPM} 目录。 更多信息请参阅《Yocto Project 概览与概念手册》的 “软件包源”一节。

7.1.17 do_packagedata

将 do_package 生成的软件包元数据保存到 PKGDATA_DIR,使其全局可用。

7.1.18 do_patch

定位补丁文件,并将其应用到源码。

获取并解包源码文件后,构建系统使用配方的 SRC_URI 语句 定位补丁文件并将其应用到源码。

备注

搜索补丁时,构建系统使用 FILESPATH 变量确定默认目录集合。

默认补丁文件为 *.patch 和 *.diff,创建并保存在配方文件所在目录 的子目录中。例如,OpenEmbedded-Core (OE-Core) 层的 bluez5 配方位于:

meta/recipes-connectivity/bluez5

该配方有两个补丁文件,位于:

meta/recipes-connectivity/bluez5/bluez5

在 bluez5 配方中,SRC_URI 语句指向构建软件包所需的源码和补丁文件。

备注

对于 bluez5_5.48.bb 配方,SRC_URI 语句来自 被包含的 bluez5.inc 文件。

如前所述,构建系统将 .patch 和 .diff 类型的文件视为补丁。 也可以在 SRC_URI 语句中使用“apply=yes”参数, 将任意文件指定为补丁文件:

SRC_URI = " \
    git://path_to_repo/some_package \
    file://file;apply=yes \
    "

反过来,如果某文件的类型为 .patch 或 .diff, 但不希望 do_patch 在补丁阶段应用它, 可以在 SRC_URI 语句中使用“apply=no”参数:

SRC_URI = " \
    git://path_to_repo/some_package \
    file://file1.patch \
    file://file2.patch;apply=no \
    "

在上例中,file1.patch 默认会作为补丁应用,而 file2.patch 不会应用。

有关补丁过程的更多信息,请参阅《Yocto Project 概览与概念手册》的 “打补丁”一节, 以及《Yocto Project 开发任务手册》的 “修补代码”一节。

7.1.19 do_populate_lic

写入配方的许可证信息,以便之后在构建镜像时收集。

7.1.20 do_populate_sdk

创建可安装 SDK 的文件和目录结构。 更多信息请参阅《Yocto Project 概览与概念手册》的 “生成 SDK”一节。

7.1.21 do_populate_sdk_ext

创建可安装的可扩展 SDK(eSDK)的文件和目录结构。 更多信息请参阅《Yocto Project 概览与概念手册》的 “生成 SDK”一节。

7.1.22 do_populate_sysroot

将 do_install 安装的部分文件暂存(复制)到相应系统根目录。 有关如何从其他配方访问这些文件的信息,请参阅 STAGING_DIR* 变量。 默认不复制其他配方在构建时通常不需要的目录,例如 /etc。

有关默认复制哪些目录的信息,请参阅 SYSROOT_DIRS* 变量。如果需要在构建时向其他配方提供更多或更少的目录, 可以在配方中修改这些变量。

do_populate_sysroot 是共享状态(sstate)任务, 意味着它可以通过共享状态加速。另请注意,重新执行此任务时, 会删除此前的所有输出,即先进行清理。

7.1.23 do_prepare_recipe_sysroot

根据 DEPENDS 指定的依赖,将文件安装到各配方专用的系统根目录, 即 ${WORKDIR} 下的 recipe-sysroot 和 recipe-sysroot-native。更多信息请参阅“staging”类。

7.1.24 do_recipe_qa

对配方执行完全基于配方元数据的质量检查,不需要构建产物或源码。

此任务定义的检查列表见 质量检查错误和警告消息。

7.1.25 do_rm_work

在 OpenEmbedded 构建系统不再需要工作文件后将其删除。 更多信息见“rm_work”一节。

7.1.26 do_unpack

将源码解包到 ${UNPACKDIR} 指向的工作目录。 有关源码文件解包方式的更多信息,请参阅《Yocto Project 概览与概念手册》的 “获取源码”一节。

7 手动调用的任务

这些任务通常不属于标准构建流程,因此一般需要手动触发, 例如使用 bitbake -c 命令行选项。 以 listtasks 为例,它显示某个配方定义的任务,调用方式如下:

$ bitbake -c listtasks recipename

手动调用任务的典型定义如下:

addtask listtasks
do_listtasks[nostamp] = "1"
python do_listtasks() {
   ... definition of task ...
}

此定义将函数声明为任务,但不将其纳入任何任务依赖链; 同时设置 [nostamp] 标志,确保每次调用都会运行。

7.2.1 do_checkuri

验证 SRC_URI 的值。

7.2.2 do_clean

删除目标从 do_unpack 开始的所有输出文件, 涉及 do_unpack、do_configure、 do_compile、do_install 和 do_package 等任务。

可以使用 BitBake 运行此任务:

$ bitbake -c clean recipe

此任务删除配方工作目录(由 WORKDIR 的值表示)、共享状态清单, 以及 时间戳。 但不会删除 共享状态 缓存文件。因此,如果未作任何修改,清理后重新构建配方时, 只会从共享状态缓存恢复输出文件。 若要删除配方的共享状态缓存文件,应改用 do_cleansstate 任务,即 bitbake -c cleansstate recipe。

7.2.3 do_cleanall

删除目标的所有输出文件、 共享状态 缓存, 以及下载的源码文件(即 DL_DIR 中的内容)。 本质上,do_cleanall 与 do_cleansstate 相同, 只是还会删除下载的源码文件。

可以使用 BitBake 运行此任务:

$ bitbake -c cleanall recipe

正常场景下不应使用 do_cleanall。 如果希望重新开始 do_fetch,应改用:

$ bitbake -f -c fetch recipe

备注

推荐 bitbake -f -c fetch,是因为 do_cleanall 在某些情况下会导致问题,例如:

$ bitbake -c fetch    recipe
$ bitbake -c cleanall recipe-native
$ bitbake -c unpack   recipe

第 1 步后,recipe 的 do_fetch 任务已有时间戳文件。 第 2 步使用不同的工作目录,因此不会删除该时间戳。 第 3 步的解包任务随后尝试解压下载的归档, 却因该归档已在第 2 步删除而失败。

配置了共享下载目录(DL_DIR)时, 并发的 BitBake 进程也会遇到同样的问题。

7.2.4 do_cleansstate

删除目标的全部输出文件和 共享状态 缓存。 本质上,do_cleansstate 与 do_clean 相同, 只是还会删除 共享状态 缓存。

可以使用 BitBake 运行此任务:

$ bitbake -c cleansstate recipe

运行 do_cleansstate 后,OpenEmbedded 构建系统 不再使用相应共享状态,因此保证配方从头构建。

备注

不建议对共享的 SSTATE_DIR 使用 do_cleansstate, 因为这可能导致另一个 BitBake 实例的构建报错。 构建会预先检查共享状态,但稍后才读取相应文件; 如果文件在此期间被删除,就会报错。 不过这不会导致完全失败,因为构建会重新生成产物。

强制重新构建的可靠且推荐方式是改用 bitbake -f。

备注

do_cleansstate 无法从远程共享状态镜像站删除共享状态。 如果使用远程镜像站又需要从头构建目标,应使用“-f”选项,如下所示:

$ bitbake -f -c do_cleansstate target

7.2.5 do_pydevshell

启动一个 shell,通过交互式 Python 解释器与 BitBake 构建环境交互。 在此 shell 中,可以直接查看和设置数据存储中的内容, 并像在 BitBake 环境内一样执行函数。 有关 pydevshell 的更多信息,请参阅《Yocto Project 开发任务手册》的 “使用 Python 开发 Shell”一节。

7.2.6 do_devshell

启动一个为开发、调试或两者共同使用而设置好环境的 shell。 有关 devshell 的更多信息,请参阅《Yocto Project 开发任务手册》的 “使用开发 Shell”一节。

7.2.7 do_list_image_features

列出镜像配方可用的功能。 这些功能可以通过 IMAGE_FEATURES 或 EXTRA_IMAGE_FEATURES 设置。

7.2.8 do_listtasks

列出目标定义的全部任务。

7.2.9 do_package_index

在 软件包源 区域创建或更新索引。

备注

与本节其他任务不同,此任务不通过 bitbake -c 命令行选项触发。 它专用于 package-index 配方,应使用 bitbake package-index 运行。