3 个常见任务
目录
3.2.2使用自定义IMAGE_FEATURES和自定义图像EXTRA_IMAGE_FEATURES
3.10.3构建初始 RAM 文件系统 (initramfs) 映像
3.18.3特定于 OpenEmbedded 构建系统的注意事项
3.24.2主镜像使用systemd,救援镜像使用SysVinit
3.30.13使用 GNU 项目调试器 (GDB) 远程调试
3.30.14在目标上使用 GNU 项目调试器 (GDB) 进行调试
本章介绍了基本过程,例如创建层、添加新软件包、扩展或自定义映像、将工作移植到新硬件(添加新机器)等。您会发现此处记录的过程经常出现在使用 Yocto 项目的开发周期中。
3.1理解和创建层
OpenEmbedded 构建系统支持将元数据组织 成多个层。图层允许您将不同类型的自定义相互隔离。有关 Yocto 项目层模型的介绍性信息,请参阅Yocto 项目概述和概念手册中的“ Yocto 项目层模型”部分。
3.1.1创建你自己的层
创建您自己的层以与 OpenEmbedded 构建系统一起使用非常容易。Yocto 项目附带了加速创建图层的工具。本节介绍您手动执行创建图层的步骤,以便您更好地理解它们。有关层创建工具的信息,请参阅Yocto 项目板支持包 (BSP) 开发人员指南中的“使用 bitbake-layers 脚本创建新的 BSP 层”部分和“使用 bitbake-layers 脚本创建通用层”部分” 部分在本手册的更下方。
请按照以下常规步骤在不使用工具的情况下创建图层:
-
检查现有图层:在创建新图层之前,您应该确保有人尚未创建包含您需要的元数据的图层。您可以在OpenEmbedded 元数据索引中 查看 OpenEmbedded 社区中可用于 Yocto 项目的层列表。您可以找到与您需要的相同或接近的图层。
-
创建目录:为您的图层创建目录。创建层时,请确保在与 Yocto 项目源目录 (例如克隆的
poky
存储库)无关的区域中创建目录。虽然不是严格要求,但在目录名称前加上字符串“meta-”。例如:
meta-mylayer meta-GUI_xyz meta-mymachine
除了极少数例外,图层的名称遵循以下形式:
meta-root_name
当工具、组件或变量“假定”您的图层名称以“meta-”开头时,遵循此图层命名约定可以为您省去麻烦。一个值得注意的例子是在配置文件中,如以下步骤所示,其中没有“meta-”字符串的层名称被附加到配置中使用的几个变量。
-
创建图层配置文件:在新图层文件夹中,您需要创建一个
conf/layer.conf
文件。最简单的方法是获取现有的层配置文件并将其复制到层的conf
目录中,然后根据需要修改该文件。meta-yocto-bsp/conf/layer.conf
Yocto 项目源代码库中的文件 演示了所需的语法。对于您的图层,您需要将“yoctobsp”替换为您图层的唯一标识符(例如,对于名为“meta-machinexyz”的图层,请使用“machinexyz”):# We have a conf and classes directory, add to BBPATH BBPATH .= ":${LAYERDIR}" # We have recipes-* directories, add to BBFILES BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ ${LAYERDIR}/recipes-*/*/*.bbappend" BBFILE_COLLECTIONS += "yoctobsp" BBFILE_PATTERN_yoctobsp = "^${LAYERDIR}/" BBFILE_PRIORITY_yoctobsp = "5" LAYERVERSION_yoctobsp = "4" LAYERSERIES_COMPAT_yoctobsp = "dunfell"
下面是层配置文件的解释:
-
BBPATH : 将层的根目录添加到 BitBake 的搜索路径。通过使用 BBPATH变量,BitBake 可以定位类文件 (
.bbclass
)、配置文件以及包含在include
和require
语句中的文件。对于这些情况,BitBake 使用与BBPATH 中找到的名称匹配的第一个文件。这类似于将PATH
变量用于二进制文件的方式。因此,建议您在自定义层中使用唯一的类和配置文件名。 -
BBFILES:定义层中所有配方的位置。
-
BBFILE_COLLECTIONS:通过在整个 OpenEmbedded 构建系统中用于引用层的唯一标识符来建立当前层。在这个例子中,标识符“yoctobsp”是名为“meta-yocto-bsp”的容器层的表示。
-
BBFILE_PATTERN:在解析过程中立即扩展以提供层的目录。
-
BBFILE_PRIORITY:当 OpenEmbedded 构建在不同层中找到相同名称的配方时,为层中的配方建立优先级。
-
LAYERVERSION:建立层的版本号。使用LAYERDEPENDS 变量时,您可以使用此版本号将层的此确切版本指定为依赖 项。
-
LAYERDEPENDS:列出该层所依赖的所有层(如果有)。
-
LAYERSERIES_COMPAT:列出 当前版本兼容的Yocto 项目版本。此变量是指示您的特定图层是否为当前图层的好方法。
-
-
添加内容:根据图层类型,添加内容。如果层添加了对机器的支持,则
conf/machine/
在层内的文件中添加机器配置。如果该层添加了发行版策略,则conf/distro/
在该图层内的文件中添加发行版配置。如果图层引入了新配方,请将您需要的配方放在recipes-*
图层内的子目录中。注意
有关符合 Yocto 项目的层层次结构的说明,请参阅Yocto 项目板支持包 (BSP) 开发人员指南中的“示例文件系统布局”部分。
-
(可选)测试兼容性:如果您希望获得在您的图层或使用您的图层的应用程序中使用 Yocto 项目兼容性徽标的权限,请执行申请兼容性的步骤。有关更多信息,请参阅“确保您的图层与 Yocto 项目兼容”部分。
3.1.2创建图层时遵循最佳实践
要创建更易于维护且不会影响其他机器的构建的层,您应该考虑以下列表中的信息:
-
避免在您的配置中“覆盖”来自其他层的整个配方:换句话说,不要将整个配方复制到您的层中,然后对其进行修改。相反,使用附加文件 (
.bbappend
) 仅覆盖您需要修改的原始配方的那些部分。 -
避免重复包含文件:
.bbappend
为每个使用包含文件的配方使用附加文件 ( )。或者,如果您要引入需要包含文件的新配方,请使用相对于原始图层目录的路径来引用该文件。例如,使用package file而不是file。如果您发现必须覆盖包含文件,则可能表明包含文件在它最初所属的层中存在缺陷。如果是这种情况,您应该尝试解决该缺陷,而不是覆盖包含文件。例如,您可以通过让包含文件的维护者添加一个或多个变量来轻松覆盖需要覆盖的部分来解决此问题。require recipes-core/
/
.inc
require
.inc
-
构建您的图层:在附加文件中正确使用覆盖并将特定于机器的文件放置在您的图层中可以确保构建不会使用错误的元数据并对不同机器的构建产生负面影响。以下是一些示例:
-
修改变量以支持不同的机器:假设您有一个名为的层
meta-one
,它添加了对构建机器“one”的支持。为此,您可以使用名为base-files.bbappend
“foo”的附加文件 并通过更改DEPENDS 变量创建对“foo”的依赖:DEPENDS = "foo"
在任何包含 layer 的构建过程中都会创建依赖项
meta-one
。但是,您可能不希望所有机器都具有这种依赖性。例如,假设您正在为机器“two”构建,但您的bblayers.conf
文件包含meta-one
层。在构建过程中,base-files
for 机器“two”也将依赖于foo
.要确保您的更改仅在构建机器“one”时适用,请使用机器覆盖和DEPENDS语句:
DEPENDS:one = "foo"
使用
:append
和:prepend
操作时也应遵循相同的策略:DEPENDS:append:one = " foo" DEPENDS:prepend:one = "foo "
作为一个实际示例,这里是通用内核包含文件的一个片段
linux-yocto.inc
,其中内核编译和链接选项在支持架构的子集的情况下进行了调整:DEPENDS:append:aarch64 = " libgcc" KERNEL_CC:append:aarch64 = " ${TOOLCHAIN_OPTIONS}" KERNEL_LD:append:aarch64 = " ${TOOLCHAIN_OPTIONS}" DEPENDS:append:nios2 = " libgcc" KERNEL_CC:append:nios2 = " ${TOOLCHAIN_OPTIONS}" KERNEL_LD:append:nios2 = " ${TOOLCHAIN_OPTIONS}" DEPENDS:append:arc = " libgcc" KERNEL_CC:append:arc = " ${TOOLCHAIN_OPTIONS}" KERNEL_LD:append:arc = " ${TOOLCHAIN_OPTIONS}" KERNEL_FEATURES:append:qemuall=" features/debug/printk.scc"
注意
还建议避免“+=”和“=+”并使用特定于机器的
:append
和:prepend
操作。 -
将特定于机器的文件放置在特定于机器的位置:当您有一个基本配方(例如
base-files.bb
,包含文件的 SRC_URI语句)时,您可以使用附加文件使构建使用您自己的文件版本。例如,您的图层中的附加文件meta-one/recipes-core/base-files/base-files.bbappend
可以使用FILESEXTRAPATHS扩展FILESPATH,如下所示:FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:"
只要您将文件放在
meta-one/recipes-core/base-files/base-files/
. 但是,如果您正在为另一台机器构建并且bblayers.conf
文件包含meta-one
层,并且您的机器特定文件的位置是根据FILESPATH找到该文件的第一个位置,则所有机器的构建也将使用该机器特定文件.您可以通过将文件放在特定于机器的子目录中来确保特定机器的文件用于特定机器。例如,不是将文件放入
meta-one/recipes-core/base-files/base-files/
如上所示,而是将其 放入meta-one/recipes-core/base-files/base-files/one/
. 这不仅确保文件仅在为机器“one”构建时使用,而且构建过程可以更快地定位文件。
-
-
执行申请 Yocto 项目兼容性的步骤:如果您希望在您的图层或使用您的图层的应用程序中使用 Yocto 项目兼容性徽标,请执行申请兼容性的步骤。有关更多信息,请参阅“确保您的图层与 Yocto 项目兼容”部分。
-
遵循层命名约定:将自定义层存储在使用该
meta-layer_name
格式的 Git 存储库中。 -
本地分组您的图层:将您的存储库与源目录中的其他克隆
meta
目录一起克隆。
3.1.3确保你的层与 Yocto 项目兼容
当您创建与 Yocto 项目一起使用的层时,确保该层与现有的 Yocto 项目层交互良好是有利的(即该层与 Yocto 项目兼容)。确保兼容性使 Yocto 项目社区中的其他人可以轻松使用该层,并允许您使用 Yocto 项目兼容徽标。
注意
只有 Yocto 项目成员组织被允许使用 Yocto 项目兼容标志。该徽标不可用于一般用途。有关如何成为 Yocto 项目成员组织的信息,请参阅Yocto 项目网站。
Yocto 项目兼容性计划包含一个层应用程序流程,该流程请求许可为您的层和应用程序使用 Yocto 项目兼容性徽标。该过程由两部分组成:
-
成功传递一个脚本 (
yocto-check-layer
),当针对您的层运行时,根据层在现实世界中的工作方式以及发现的缺陷的经验,根据约束对其进行测试。成功的兼容性注册需要从脚本中获取“PASS”结果。 -
完成申请接受表,您可以在https://www.yoctoproject.org/webform/yocto-project-compatible-registration找到该表 。
要获得使用徽标的许可,您需要满足以下条件:
-
在针对您的图层运行脚本时,能够选中表示您获得“PASS”的框。
-
对表格上的问题回答“是”,或者对回答“否”的任何问题做出可接受的解释。
-
成为 Yocto 项目成员组织。
本节的其余部分介绍有关注册表和yocto-check-layer
脚本的信息。
3.1.3.1 Yocto 项目兼容程序申请
使用表格申请您的图层批准。成功应用后,您可以将 Yocto 项目兼容性徽标与您的层和使用您的层的应用程序一起使用。
要访问该表单,请使用此链接:https : //www.yoctoproject.org/webform/yocto-project-compatible-registration。按照表格上的说明完成您的申请。
该应用程序由以下部分组成:
-
联系信息:根据字段要求提供您的联系信息。连同您的信息,提供与您的图层兼容的 Yocto 项目的已发布版本。
-
验收标准:为检查表中的每个项目提供“是”或“否”的答案。对于您回答“否”的项目,表格底部有任何解释的空间。
-
建议:提供有关 Linux 内核使用和构建成功的问题的答案。
3.1.3.2yocto-check-layer
脚本
该yocto-check-layer
脚本为您提供了一种评估图层与 Yocto 项目兼容程度的方法。您应该在使用表单之前运行此脚本以申请上一节中所述的兼容性。您需要获得“通过”结果才能成功处理您的申请表。
该脚本将测试分为三个区域:COMMON、BSP 和 DISTRO。例如,给定一个分布层 (DISTRO),该层必须通过 COMMON 和 DISTRO 相关测试。此外,如果您的层是 BSP 层,则该层必须通过 COMMON 和 BSP 测试集。
要执行脚本,请从构建目录输入以下命令:
$ source oe-init-build-env
$ yocto-check-layer your_layer_directory
请务必在命令中提供图层的实际目录。
输入命令会使脚本确定层的类型,然后对层执行一组特定的测试。以下列表概述了测试:
-
common.test_readme
: 测试README
层中是否存在文件且文件不为空。 -
common.test_parse
:测试以确保 BitBake 可以正确解析文件(即)。bitbake -p
-
common.test_show_environment
:测试全局或每个配方环境是否有序且没有错误(即)。bitbake -e
-
common.test_world
: 验证有效。bitbake world
-
common.test_signatures
:测试以确保 BSP 和 DISTRO 层不会随附更改签名的配方。 -
common.test_layerseries_compat
:验证层兼容性设置是否正确。 -
bsp.test_bsp_defines_machines
: 测试 BSP 层是否有机器配置。 -
bsp.test_bsp_no_set_machine
:测试以确保 BSP 层在添加层时不会设置机器。 -
bsp.test_machine_world
:验证无论选择哪台机器都有效。bitbake world
-
bsp.test_machine_signatures
:验证针对特定机器的构建仅影响特定于该机器的任务的签名。 -
distro.test_distro_defines_distros
:测试 DISTRO 层是否具有发行版配置。 -
distro.test_distro_no_set_distros
:测试以确保 DISTRO 层在添加层时不会设置分布。
3.1.4启用层
在 OpenEmbedded 构建系统可以使用您的新层之前,您需要启用它。要启用您的图层,只需将您的图层路径添加到文件中的 BBLAYERS变量conf/bblayers.conf
,该变量位于Build Directory 中。以下示例显示了如何启用名为 的图层 meta-mylayer
:
# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
POKY_BBLAYERS_CONF_VERSION = "2"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= " \
/home/user/poky/meta \
/home/user/poky/meta-poky \
/home/user/poky/meta-yocto-bsp \
/home/user/poky/meta-mylayer \
"
BitBakeconf/layer.conf
按照文件中BBLAYERS变量中的指定从上到下解析每个conf/bblayers.conf
文件。在处理每个conf/layer.conf
文件的过程中,BitBake 将包含在特定层中的配方、类和配置添加到源目录中。
3.1.5在你的层中附加其他层的元数据
将元数据附加到另一个配方的配方称为 BitBake 附加文件。BitBake 附加文件使用.bbappend
文件类型后缀,而将元数据附加到的相应配方使用.bb
文件类型后缀。
您可以使用.bbappend
图层中的文件对另一个图层的配方内容进行添加或更改,而无需将其他图层的配方复制到您的图层中。您的.bbappend
文件驻留在您的层中,而.bb
您附加元数据的主配方文件驻留在不同的层中。
能够将信息附加到现有配方不仅可以避免重复,还可以自动将不同层的配方更改应用到您的层中。如果您正在复制配方,则必须在更改发生时手动合并更改。
创建附加文件时,必须使用与相应配方文件相同的根名称。例如,附加文件 someapp_3.1.bbappend
必须适用于someapp_3.1.bb
. 这意味着原始配方和附加文件名是特定于版本号的。如果相应的配方被重命名以更新到更新的版本,您还必须重命名并可能更新相应的配方.bbappend
。在构建过程中,如果 BitBake 检测到一个.bbappend
文件没有具有匹配名称的相应配方,则在启动时会显示错误。有关 如何处理此错误的信息,请参阅 BB_DANGLINGAPPENDS_WARNONLY变量。
3.1.5.1使用图层覆盖文件
例如,请考虑来自Source Directory的主要外形规格配方和相应的外形规格附加文件。这是主要的外形配方,它被命名formfactor_0.0.bb
并位于“元”层中meta/recipes-bsp/formfactor
:
SUMMARY = "Device formfactor information"
DESCRIPTION = "A formfactor configuration file provides information about the \
target hardware for which the image is being built and information that the \
build system cannot obtain from other sources such as the kernel."
SECTION = "base"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
PR = "r45"
SRC_URI = "file://config file://machconfig"
S = "${WORKDIR}"
PACKAGE_ARCH = "${MACHINE_ARCH}"
INHIBIT_DEFAULT_DEPS = "1"
do_install() {
# Install file only if it has contents
install -d ${D}${sysconfdir}/formfactor/
install -m 0644 ${S}/config ${D}${sysconfdir}/formfactor/
if [ -s "${S}/machconfig" ]; then
install -m 0644 ${S}/machconfig ${D}${sysconfdir}/formfactor/
fi
}
在主要配方中,注意SRC_URI 变量,它告诉 OpenEmbedded 构建系统在构建期间在哪里查找文件。
以下是formfactor_0.0.bbappend
名为meta-raspberrypi
. 该文件位于以下图层中recipes-bsp/formfactor
:
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
默认情况下,构建系统使用 FILESPATH变量来定位文件。此附加文件通过设置FILESEXTRAPATHS 变量来扩展位置 。在.bbappend
文件中设置此变量是将目录添加到构建系统用于查找文件的搜索路径的最可靠和推荐的方法。
此示例中的语句扩展目录以包含 ${
THISDIR }/${
PN}
,该目录解析为formfactor
在附加文件所在的同一目录中命名的目录(即 meta-raspberrypi/recipes-bsp/formfactor
. 这意味着您必须设置支持目录结构,该结构将包含任何文件或您将从图层中包含的补丁。
:=
由于对THISDIR的引用,使用立即扩展赋值运算符很重要。尾随冒号字符很重要,因为它确保列表中的项目保持冒号分隔。
注意
BitBake 自动定义了THISDIR变量。你永远不应该自己设置这个变量。使用“:prepend”作为FILESEXTRAPATHS 的一部分 可确保您的路径在最终列表中的其他路径之前被搜索。
此外,并非所有追加文件都会添加额外文件。许多附加文件只允许添加构建选项(例如systemd
)。对于这些情况,您的附加文件甚至不会使用FILESEXTRAPATHS语句。
该.bbappend
文件的最终结果是,在树莓派上, rpi
将存在于OVERRIDES列表中,该文件 meta-raspberrypi/recipes-bsp/formfactor/formfactor/rpi/machconfig
将在do_fetch期间使用,并且在do_install 中对非零文件大小的测试 将返回 true,该文件将被安装。
3.1.6优先考虑你的层
每个层都分配了一个优先级值。如果多个层中存在同名的配方文件,则优先级值控制哪个层优先。对于这些情况,来自具有更高优先级编号的层的配方文件优先。优先级值还会影响.bbappend
应用同一配方的多个文件的顺序。您可以手动指定优先级,也可以让构建系统根据层的依赖关系计算它。
要手动指定图层的优先级,请使用 BBFILE_PRIORITY 变量并附加图层的根名称:
BBFILE_PRIORITY_mylayer = "1"
3.1.7管理层
您可以使用 BitBake 层管理工具bitbake-layers
来查看跨多层项目的配方结构。能够生成报告配置层及其路径和优先级以及.bbappend
文件及其适用配方的输出有助于揭示潜在问题。
有关 BitBake 层管理工具的帮助,请使用以下命令:
$ bitbake-layers --help
NOTE: Starting bitbake server...
usage: bitbake-layers [-d] [-q] [-F] [--color COLOR] [-h] <subcommand> ...
BitBake layers utility
optional arguments:
-d, --debug Enable debug output
-q, --quiet Print only errors
-F, --force Force add without recipe parse verification
--color COLOR Colorize output (where COLOR is auto, always, never)
-h, --help show this help message and exit
subcommands:
<subcommand>
layerindex-fetch Fetches a layer from a layer index along with its
dependent layers, and adds them to conf/bblayers.conf.
layerindex-show-depends
Find layer dependencies from layer index.
add-layer Add one or more layers to bblayers.conf.
remove-layer Remove one or more layers from bblayers.conf.
flatten flatten layer configuration into a separate output
directory.
show-layers show current configured layers.
show-overlayed list overlayed recipes (where the same recipe exists
in another layer)
show-recipes list available recipes, showing the layer they are
provided by
show-appends list bbappend files and recipe files they apply to
show-cross-depends Show dependencies between recipes that cross layer
boundaries.
create-layer Create a basic layer
Use bitbake-layers <subcommand> --help to get help on a specific command
以下列表描述了可用的命令:
-
help:
显示一般帮助或指定命令的帮助。 -
show-layers:
显示当前配置的层。 -
show-overlayed:
列出重叠的食谱。当具有更高层优先级的另一个层中存在具有相同名称的配方时,将覆盖该配方。 -
show-recipes:
列出可用的配方和提供它们的层。 -
show-appends:
列出.bbappend
文件和它们适用的配方文件。 -
show-cross-depends:
列出跨越层边界的配方之间的依赖关系。 -
add-layer:
将图层添加到bblayers.conf
. -
remove-layer:
删除一个图层bblayers.conf
-
flatten:
将图层配置展平到单独的输出目录中。扁平化层配置会构建一个“扁平化”目录,其中包含所有层的内容,删除任何覆盖的配方并将任何.bbappend
文件附加到相应的配方中。您可能需要对展平层执行一些手动清理,如下所示:-
非配方文件(如补丁)被覆盖。flatten 命令显示这些文件的警告。
-
超出正常图层设置的任何内容都已添加到
layer.conf
文件中。仅使用最低优先级的层layer.conf
。 -
.bbappend
需要清理文件中覆盖和附加的项目。每个的内容.bbappend
最终都在扁平化的配方中。但是,如果有附加或更改的变量值,您需要自己整理这些。考虑以下示例。在这里,该bitbake-layers
命令添加了该行,以便您知道以下几行的来源:#### bbappended ...
... DESCRIPTION = "A useful utility" ... EXTRA_OECONF = "--enable-something" ... #### bbappended from meta-anotherlayer #### DESCRIPTION = "Customized utility" EXTRA_OECONF += "--enable-somethingelse"
理想情况下,您可以按如下方式整理这些实用程序:
... DESCRIPTION = "Customized utility" ... EXTRA_OECONF = "--enable-something --enable-somethingelse" ...
-
-
layerindex-fetch
:从图层索引中获取图层及其从属图层,并将图层添加到conf/bblayers.conf
文件中。 -
layerindex-show-depends
:从图层索引中查找图层依赖项。 -
create-layer
:创建一个基本层。
3.1.8使用bitbake-layers
脚本创建通用图层
bitbake-layers
带有create-layer
子命令的脚本简化了创建新的通用层的过程。
注意
-
有关 BSP 层的信息,请参阅Yocto 项目板特定 (BSP) 开发人员指南中的“ BSP 层”部分。
-
为了在 OpenEmbedded 构建系统中使用一个层,您需要将该层添加到您的
bblayers.conf
配置文件中。有关更多信息,请参阅“使用 bitbake-layers 脚本添加图层”部分。
使用此子命令的脚本操作的默认模式是使用以下内容创建图层:
-
层优先级为 6。
-
一个
conf
包含子目录layer.conf
的文件。 -
一个
recipes-example
包含名为进一步的子目录下的子目录example
,其中包含一个example.bb
配方文件。 -
A
COPYING.MIT
,这是层的许可声明。该脚本假定您要使用 MIT 许可证,这对于大多数层来说是典型的,用于层本身的内容。 -
一个
README
文件,它是一个描述新图层内容的文件。
在最简单的形式中,您可以使用以下命令形式来创建图层。该命令在当前目录中创建一个名称对应于“your_layer_name”的图层:
$ bitbake-layers create-layer your_layer_name
例如,以下命令会meta-scottrif
在您的主目录中创建一个名为的图层:
$ cd /usr/home
$ bitbake-layers create-layer meta-scottrif
NOTE: Starting bitbake server...
Add your new layer with 'bitbake-layers add-layer meta-scottrif'
如果要将图层的优先级设置为默认值“6”以外的值,可以使用该--priority
选项,也可以在脚本创建后编辑 BBFILE_PRIORITY值conf/layer.conf
。此外,如果您想为示例配方文件指定默认名称以外的名称,则可以使用该--example-recipe-name
选项。
查看命令如何工作的最简单方法是试验脚本。您还可以通过输入以下内容来阅读使用信息:bitbake-layers create-layer
$ bitbake-layers create-layer --help
NOTE: Starting bitbake server...
usage: bitbake-layers create-layer [-h] [--priority PRIORITY]
[--example-recipe-name EXAMPLERECIPE]
layerdir
Create a basic layer
positional arguments:
layerdir Layer directory to create
optional arguments:
-h, --help show this help message and exit
--priority PRIORITY, -p PRIORITY
Layer directory to create
--example-recipe-name EXAMPLERECIPE, -e EXAMPLERECIPE
Filename of the example recipe
3.1.9使用bitbake-layers
脚本添加图层
创建通用图层后,必须将其添加到 bblayers.conf
文件中。将层添加到此配置文件使 OpenEmbedded 构建系统知道您的层,以便它可以搜索它的元数据。
使用以下命令添加图层:bitbake-layers add-layer
$ bitbake-layers add-layer your_layer_name
下面是一个meta-scottrif
向配置文件中添加命名层的示例。在添加图层的命令之后是另一个bitbake-layers
显示bblayers.conf
文件中图层的命令:
$ bitbake-layers add-layer meta-scottrif
NOTE: Starting bitbake server...
Parsing recipes: 100% |##########################################################| Time: 0:00:49
Parsing of 1441 .bb files complete (0 cached, 1441 parsed). 2055 targets, 56 skipped, 0 masked, 0 errors.
$ bitbake-layers show-layers
NOTE: Starting bitbake server...
layer path priority
==========================================================================
meta /home/scottrif/poky/meta 5
meta-poky /home/scottrif/poky/meta-poky 5
meta-yocto-bsp /home/scottrif/poky/meta-yocto-bsp 5
workspace /home/scottrif/poky/build/workspace 99
meta-scottrif /home/scottrif/poky/build/meta-scottrif 6
将层添加到此文件使构建系统能够在构建期间定位层。
注意
在构建过程中,OpenEmbedded 构建系统按照列表的顶部到底部的顺序查看层。
3.2自定义图片
您可以自定义图像以满足特定要求。本节介绍了几种方法并为每种方法提供了指南。
3.2.1自定义图像使用local.conf
自定义图像的最简单方法可能是通过local.conf
配置文件添加包。由于仅限于本地使用,这种方式一般只允许添加包,不如创建自己的自定义镜像灵活。当您以这种方式使用局部变量添加包时,您需要意识到这些变量更改对每个构建都有效,因此会影响所有图像,这可能不是您所需要的。
要使用本地配置文件将包添加到您的映像,请将IMAGE_INSTALL变量与:append
运算符一起使用:
IMAGE_INSTALL:append = " strace"
语法的使用很重要——特别是引号和包名之间的空格, strace
在这个例子中。由于:append
操作员不添加空格,因此需要此空格。
此外,如果您想避免排序问题,您必须使用:append
代替+=
运算符。这样做的原因是因为这样做会无条件地附加到变量并避免由于在图像配方和.bbclass
文件中设置变量而导致的排序问题,例如?=
. 使用:append
确保操作生效。
如其最简单的使用所示,IMAGE_INSTALL:append
影响所有图像。可以扩展语法,以便变量仅适用于特定图像。下面是一个例子:
IMAGE_INSTALL:append:pn-core-image-minimal = " strace"
此示例仅添加strace
到core-image-minimal
图像。
您可以通过CORE_IMAGE_EXTRA_INSTALL变量使用类似的方法添加包 。如果使用此变量,则只会 core-image-*
影响图像。
3.2.2使用自定义IMAGE_FEATURES
和自定义图像EXTRA_IMAGE_FEATURES
另一种自定义图像的方法是使用IMAGE_FEATURES和 EXTRA_IMAGE_FEATURES 变量启用或禁用高级图像功能 。虽然这两个变量的函数几乎等同,最佳实践要求使用IMAGE_FEATURES从配方中使用EXTRA_IMAGE_FEATURES从您的内部 local.conf
文件,该文件是在发现 建目录。
要了解这些功能的工作原理,最好的参考是 meta/classes/image.bbclass
. 此类列出了可用的 IMAGE_FEATURES,其中大多数映射到包组,而一些(例如debug-tweaks
和read-only-rootfs
)解析为常规配置设置。
总之,该文件查看IMAGE_FEATURES 变量的内容,然后相应地映射或配置该功能。基于此信息,构建系统自动将适当的包或配置添加到 IMAGE_INSTALL变量。实际上,您通过扩展类或创建用于专用图像.bb
文件的自定义类来启用额外的功能。
使用本地配置文件中的EXTRA_IMAGE_FEATURES变量。使用单独的区域来启用具有此变量的功能可帮助您避免覆盖图像配方中使用IMAGE_FEATURES启用的功能。EXTRA_IMAGE_FEATURES的值 添加到IMAGE_FEATURES内 meta/conf/bitbake.conf
。
为了说明如何使用这些变量来修改图像,请考虑一个选择 SSH 服务器的示例。Yocto 项目附带了两个可用于图像的 SSH 服务器:Dropbear 和 OpenSSH。Dropbear 是适用于资源受限环境的最小 SSH 服务器,而 OpenSSH 是众所周知的标准 SSH 服务器实现。默认情况下,core-image-sato
映像配置为使用 Dropbear。在core-image-full-cmdline
和core-image-lsb
图像都包括OpenSSH的。该core-image-minimal
映像不包含 SSH 服务器。
您可以自定义图像并更改这些默认值。编辑 IMAGE_FEATURES在你的食谱变量或使用 EXTRA_IMAGE_FEATURES在你的local.conf
文件,以便配置您正在使用包括图像 ssh-server-dropbear
或ssh-server-openssh
。
注意
有关Yocto 项目附带的图像功能的完整列表,请参阅Yocto 项目参考手册中的“图像功能”部分。
3.2.3使用自定义 .bb 文件自定义图像
您还可以通过创建自定义配方来自定义图像,该配方将附加软件定义为图像的一部分。以下示例显示了您需要的两行的表格:
IMAGE_INSTALL = "packagegroup-core-x11-base package1 package2"
inherit core-image
使用自定义配方定义软件可让您完全控制图像的内容。在IMAGE_INSTALL变量中使用正确的包名称很重要。对于名称,您必须使用 OpenEmbedded 表示法而不是 Debian 表示法(例如 glibc-dev
代替libc6-dev
)。
创建自定义图像的另一种方法是基于现有图像。例如,如果您想基于创建一个图像 core-image-sato
但将附加包添加strace
到该图像,请将其复制meta/recipes-sato/images/core-image-sato.bb
到一个新的 .bb
并将以下行添加到副本的末尾:
IMAGE_INSTALL += "strace"
3.2.4使用自定义包组自定义镜像
对于复杂的自定义映像,自定义映像的最佳方法是创建用于构建一个或多个映像的自定义包组配方。包组配方的一个很好的例子是 meta/recipes-core/packagegroups/packagegroup-base.bb
.
如果您检查该配方,您会看到PACKAGES变量列出了要生产的包组包。该 语句设置适当的默认值并自动为PACKAGES语句中指定的每个包添加 、和补充包。inherit packagegroup
-dev
-dbg
-ptest
注意
该行应该位于配方顶部附近,当然在PACKAGES语句之前。inherit packagegroup
对于您在PACKAGES 中指定的每个包,您可以使用RDEPENDS 和RRECOMMENDS条目来提供父任务包应包含的包列表。您可以在packagegroup-base.bb
配方中进一步查看这些示例。
这是一个简短的、捏造的示例,显示了 中定义的假设包组的相同基本部分packagegroup-custom.bb
,其中变量PN是缩写对完整包组名称的引用的标准方法packagegroup-custom
:
DESCRIPTION = "My Custom Package Groups"
inherit packagegroup
PACKAGES = "\
${PN}-apps \
${PN}-tools \
"
RDEPENDS:${PN}-apps = "\
dropbear \
portmap \
psplash"
RDEPENDS:${PN}-tools = "\
oprofile \
oprofileui-server \
lttng-tools"
RRECOMMENDS:${PN}-tools = "\
kernel-module-oprofile"
在前面的示例中,创建了两个包组包,其中列出了它们的依赖项和推荐的包依赖项: packagegroup-custom-apps
、 和packagegroup-custom-tools
。要使用这些包组包构建映像,您需要添加 packagegroup-custom-apps
和/或packagegroup-custom-tools
到 IMAGE_INSTALL。对于其他形式的映像依赖项,请参阅本节的其他区域。
3.2.5自定义镜像主机名
默认情况下,/etc/hostname
映像中配置的主机名(即)与机器名称相同。例如,如果 MACHINE等于“qemux86”,则写入的配置主机名/etc/hostname
是“qemux86”。
您可以通过base-files
使用附加文件或配置文件更改配方中“主机名”变量的值来自定义此名称。在附加文件中使用以下内容:
hostname = "myhostname"
在配置文件中使用以下内容:
hostname:pn-base-files = "myhostname"
在某些情况下,更改变量“主机名”的默认值可能很有用。例如,假设您需要对一个图像进行广泛的测试,并且您想从具有典型默认主机名的现有图像中轻松识别出被测图像。在这种情况下,您可以将默认主机名更改为“testme”,这会导致所有图像都使用名称“testme”。测试完成后,您不再需要重建映像进行测试,您可以轻松重置默认主机名。
另一个有趣的点是,如果您取消设置变量,图像在文件系统中将没有默认主机名。这是在配置文件中取消设置变量的示例:
hostname:pn-base-files = ""
文件系统中没有默认主机名适用于使用动态主机名的环境,例如虚拟机。
3.3编写新配方
食谱(.bb
文件)是 Yocto 项目环境中的基本组件。OpenEmbedded 构建系统构建的每个软件组件都需要一个配方来定义组件。本节介绍如何创建、编写和测试新配方。
注意
有关对配方有用的变量的信息以及有关配方命名问题的信息,请参阅Yocto 项目参考手册的“配方”部分。
3.3.1概述
下图显示了创建新配方的基本过程。本节的其余部分提供了这些步骤的详细信息。
3.3.2定位或自动创建基础配方
您始终可以从头开始编写食谱。但是,有三种选择可以帮助您快速开始使用新配方:
-
devtool add
:有助于创建配方和有利于开发的环境的命令。 -
recipetool create
:Yocto 项目提供的命令,可根据源文件自动创建基本配方。 -
现有配方:功能与您需要的配方相似的现有配方的位置和修改。
注意
有关配方语法的信息,请参阅“配方语法”部分。
3.3.2.1 使用创建基本配方devtool add
该命令使用与自动创建配方相同的逻辑,如下所列。然而,此外,设置一个环境,使您可以轻松地修补源代码并对配方进行更改,这在添加配方以构建要包含在构建中的新软件时通常是必要的。devtool add
recipetool create
devtool add
您可以在 Yocto 项目应用程序开发和可扩展软件开发工具包 (eSDK) 手册的“深入了解 devtool add ”部分中找到该命令的完整说明。devtool add
3.3.2.2 使用创建基本配方recipetool create
recipetool create
给定一组源代码文件,自动创建基本配方。只要您可以提取或指向源文件,该工具就会构造一个配方并自动将所有预构建信息配置到该配方中。例如,假设您有一个使用 Autotools 构建的应用程序。使用recipetool
结果在具有预构建依赖项、许可要求和配置的校验和的配方中创建基本配方 。
要运行该工具,您只需进入您的 构建目录并获取构建环境设置脚本(即 oe-init-build-env)。要获取有关该工具的帮助,请使用以下命令:
$ recipetool -h
NOTE: Starting bitbake server...
usage: recipetool [-d] [-q] [--color COLOR] [-h] <subcommand> ...
OpenEmbedded recipe tool
options:
-d, --debug Enable debug output
-q, --quiet Print only errors
--color COLOR Colorize output (where COLOR is auto, always, never)
-h, --help show this help message and exit
subcommands:
create Create a new recipe
newappend Create a bbappend for the specified target in the specified
layer
setvar Set a variable within a recipe
appendfile Create/update a bbappend to replace a target file
appendsrcfiles Create/update a bbappend to add or replace source files
appendsrcfile Create/update a bbappend to add or replace a source file
Use recipetool <subcommand> --help to get help on a specific command
运行会创建基本配方并将其正确定位在包含源文件的层中。以下是一些语法示例:recipetool create -o OUTFILE
使用此语法基于源生成配方。生成后,配方驻留在现有的源代码层中:
recipetool create -o OUTFILE source
使用此语法使用从源中提取的代码生成配方。提取的代码放置在由EXTERNLSRC定义的自己的层中。
recipetool create -o OUTFILE -x EXTERNALSRC source
使用此语法基于源生成配方。选项直接
recipetool
生成调试信息。生成后,配方驻留在现有的源代码层中:recipetool create -d -o OUTFILE source
3.3.2.3查找和使用类似的配方
在从头开始编写食谱之前,发现其他人是否已经编写了满足(或接近满足)您的需求的食谱通常很有用。Yocto 项目和 OpenEmbedded 社区维护着许多可能适合您正在做的事情的食谱。您可以在OpenEmbedded Layer Index 中找到这些食谱的良好中央索引 。
从现有配方或骨架配方开始工作是最好的开始方式。以下是关于这两种方法的一些要点:
-
找到并修改与您想要做的事情接近的配方: 当您熟悉当前的配方空间时,此方法有效。对于刚接触 Yocto 项目或编写食谱的人来说,该方法效果不佳。
与此方法相关的一些风险是使用的配方的区域与您尝试使用配方完成的内容完全无关,无法识别您可能必须从头开始添加的配方区域,等等。所有这些风险都源于对现有配方空间的不熟悉。
-
使用和修改以下骨架配方:如果由于某种原因您不想使用
recipetool
并且找不到接近满足您需求的现有配方,您可以使用以下结构来提供新配方的基本区域。DESCRIPTION = "" HOMEPAGE = "" LICENSE = "" SECTION = "" DEPENDS = "" LIC_FILES_CHKSUM = "" SRC_URI = ""
3.3.3存储和命名配方
一旦你有了你的基本配方,你应该把它放在你自己的层中并适当地命名。正确定位它可以确保 OpenEmbedded 构建系统在您使用 BitBake 处理配方时可以找到它。
-
存储您的配方: OpenEmbedded 构建系统通过层的
conf/layer.conf
文件和 BBFILES变量定位您的配方。此变量设置构建系统可以从中找到配方的路径。以下是典型用途:BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ ${LAYERDIR}/recipes-*/*/*.bbappend"
因此,您需要确保在图层内找到新配方,以便可以找到它。
您可以在“理解和创建图层”部分中找到有关图层结构的更多信息。
-
命名你的食谱:当你命名你的食谱时,你需要遵循这个命名约定:
basename_version.bb
使用小写字符并且不包括保留的后缀
-native
、-cross
、-initial
或-dev
随意(即除非字符串适用,否则不要将它们用作食谱名称的一部分)。以下是一些示例:cups_1.7.0.bb gawk_4.0.2.bb irssi_0.8.16-rc1.bb
3.3.4在配方上运行构建
创建新配方通常是一个迭代过程,需要使用 BitBake 多次处理配方,以便逐步发现并将信息添加到配方文件中。
假设您已经获得了构建环境设置脚本(即 oe-init-build-env)并且您在Build Directory 中,请使用 BitBake 来处理您的配方。您只需要提供 basename
上一节中描述的配方:
$ bitbake basename
在构建过程中,OpenEmbedded 构建系统为每个配方 ( ${
WORKDIR}
)创建一个临时工作目录,其中保存提取的源文件、日志文件、中间编译和打包文件等。
每个配方临时工作目录的路径取决于构建它的上下文。找到此路径的最快方法是通过运行以下命令让 BitBake 返回它:
$ bitbake -e basename | grep ^WORKDIR=
例如,假设有一个名为 的源目录顶级文件夹poky
、一个位于 的默认构建目录 poky/build
和一个qemux86-poky-linux
机器目标系统。此外,假设您的配方名为foo_1.3.0.bb
。在这种情况下,构建系统用于构建包的工作目录如下:
poky/build/tmp/work/qemux86-poky-linux/foo/1.3.0-r0
在这个目录里,你可以找到子目录,如image
, packages-split
和temp
。构建完成后,您可以检查这些内容以确定构建的进展情况。
注意
您可以在配方temp
目录(例如poky/build/tmp/work/qemux86-poky-linux/foo/1.3.0-r0/temp
)中找到每个任务的日志文件。日志文件被命名log.taskname
(例如log.do_configure
、 log.do_fetch
、 和log.do_compile
)。
您可以在 Yocto 项目概述和概念手册的“ Yocto 项目开发环境”一章中找到有关构建过程的更多信息。
3.3.5取码
您的配方必须做的第一件事是指定如何获取源文件。获取主要通过 SRC_URI变量进行控制。您的配方必须有一个指向源所在位置的SRC_URI变量。有关源位置的图形表示,请参阅Yocto 项目概述和概念手册中的“源”部分。
该do_fetch任务使用每个条目的前缀SRC_URI变量的值,以确定哪些提取器使用,让您的源文件。触发提取器的是SRC_URI变量。该do_patch任务使用可变后源提取到应用补丁。在OpenEmbedded构建系统使用 FILESOVERRIDES用于扫描目录位置在本地文件SRC_URI。
配方中的SRC_URI变量必须为源文件定义每个唯一的位置。最好不要在SRC_URI 中使用的 URL 中硬编码版本号。而不是对这些值进行硬编码,而是使用${
PV}
,这会导致获取过程使用配方文件名中指定的版本。以这种方式指定版本意味着将配方升级到未来版本就像重命名配方以匹配新版本一样简单。
这是meta/recipes-devtools/strace/strace_5.5.bb
配方中的一个简单示例, 其中源来自单个 tarball。注意PV变量的使用 :
SRC_URI = "https://strace.io/files/${PV}/strace-${PV}.tar.xz \
SRC_URI 中提到的文件名以典型的存档扩展名结尾(例如.tar
、.tar.gz
、.tar.bz2
、.zip
等),会在do_unpack任务期间自动提取 。有关指定这些类型文件的另一个示例,请参阅“自动工具包”部分。
另一种指定来源的方法是来自 SCM。对于 Git 存储库,您必须指定SRCREV并且您应该指定PV以包含带有SRCPV的修订版。这是食谱中的一个例子 meta/recipes-kernel/blktrace/blktrace_git.bb
:
SRCREV = "d6918c8832793b4205ed3bfede78c2f915c23385"
PR = "r6"
PV = "1.0.5+git${SRCPV}"
SRC_URI = "git://git.kernel.dk/blktrace.git \
file://ldflags.patch"
如果您的SRC_URI语句包含指向从远程服务器而不是版本控制系统获取的单个文件的 URL,BitBake 会尝试根据您的配方中定义的校验和验证这些文件,以确保自配方编写以来它们没有被篡改或以其他方式修改. 使用了两个校验和: SRC_URI[md5sum]
和SRC_URI[sha256sum]
。
如果您的SRC_URI变量指向多个 URL(不包括 SCM URL),您需要为每个 URL提供md5
和sha256
校验和。对于这些情况,您为每个 URL 提供一个名称作为SRC_URI 的一部分,然后在后续校验和语句中引用该名称。这是将文件中的行git.inc
和组合起来的示例 git_2.24.1.bb
:
SRC_URI = "${KERNELORG_MIRROR}/software/scm/git/git-${PV}.tar.gz;name=tarball \
${KERNELORG_MIRROR}/software/scm/git/git-manpages-${PV}.tar.gz;name=manpages"
SRC_URI[tarball.md5sum] = "166bde96adbbc11c8843d4f8f4f9811b"
SRC_URI[tarball.sha256sum] = "ad5334956301c86841eb1e5b1bb20884a6bad89a10a6762c958220c7cf64da02"
SRC_URI[manpages.md5sum] = "31c2272a8979022497ba3d4202df145d"
SRC_URI[manpages.sha256sum] = "9a7ae3a093bea39770eb96ca3e5b40bff7af0b9f6123f089d7821d0e5b8e1230"
md5
和sha256
校验和的正确值可能与上游源的下载页面上的其他签名(例如 md5
、sha1
、sha256
、GPG
等)一起使用。由于 OpenEmbedded 构建系统仅处理sha256sum
和md5sum
,因此您应该手动验证您找到的所有签名。
如果在您尝试构建配方时未指定SRC_URI校验和,或者您提供了不正确的校验和,则构建将针对每个缺失或不正确的校验和产生错误。作为错误消息的一部分,构建系统提供与获取的文件对应的校验和字符串。获得正确的校验和后,您可以将它们复制并粘贴到您的配方中,然后再次运行构建以继续。
注意
如前所述,如果上游源提供了用于验证下载的源代码的签名,您应该在设置配方中的校验和值并继续构建之前手动验证这些签名。
最后一个例子有点复杂,来自 meta/recipes-sato/rxvt-unicode/rxvt-unicode_9.20.bb
配方。该示例的SRC_URI语句将多个文件标识为配方的源文件:一个 tarball、一个补丁文件、一个桌面文件和一个图标。
SRC_URI = "http://dist.schmorp.de/rxvt-unicode/Attic/rxvt-unicode-${PV}.tar.bz2 \
file://xwc.patch \
file://rxvt.desktop \
file://rxvt.png"
当您使用file://
URI 协议指定本地文件时,构建系统会从本地机器获取文件。该路径相对于FILESPATH变量并按特定顺序搜索特定目录: ${
BP}
、 ${
BPN}
和 files
. 假定目录是配方或附加文件所在目录的子目录。有关指定这些类型文件的另一个示例,请参阅“单个 .c 文件包(Hello World!) ”部分。
前面的示例还指定了一个补丁文件。补丁文件是名称通常以.patch
或.diff
但可以以压缩后缀(例如diff.gz
和 )结尾的文件patch.bz2
。构建系统会自动应用补丁,如“补丁代码”部分所述。
3.3.6解包代码
在构建过程中, do_unpack任务使用${
S}
指向解包位置来解压源代码。
如果您从上游源存档 tarball 获取源文件,并且 tarball 的内部结构与名为${
BPN }-${
PV的顶级子目录的通用约定相匹配 }
,那么您不需要设置S。但是,如果SRC_URI指定从不使用此约定的存档或从像 Git 或 Subversion 这样的 SCM 中获取源,则您的配方需要定义S。
如果使用 BitBake 处理您的配方成功解压了源文件,您需要确保 指向的目录${S}
与源的结构匹配。
3.3.7补丁代码
有时需要在获取代码后修补代码。SRC_URI 中提到的任何文件名以这些后缀的.patch
或 .diff
或这些后缀的压缩版本结尾(例如diff.gz
被视为补丁 。do_patch任务会自动应用这些补丁。
构建系统应该能够使用“-p1”选项应用补丁(即路径中的一个目录级别将被剥离)。如果您的补丁需要剥离更多目录级别,请使用补丁的SRC_URI条目中的“striplevel”选项指定级别数。或者,如果您的补丁需要应用于补丁文件中未指定的特定子目录,请使用条目中的“patchdir”选项。
与SRC_URI 中使用引用的所有本地文件 一样file://
,您应该将补丁文件放在配方旁边的目录中,其名称与配方的基本名称(BP和 BPN)或“文件”相同。
3.3.8许可
您的配方需要同时具有 LICENSE和 LIC_FILES_CHKSUM 变量:
-
LICENSE:此变量指定软件的许可证。如果您不知道您正在构建的软件的分发许可,您应该转到源代码并查找该信息。包含此信息的典型文件包括
COPYING
、 LICENSE和README
files。您还可以在源文件顶部附近找到信息。例如,给定一个在 GNU 通用公共许可证第 2 版下获得许可的软件,您可以按如下方式设置LICENSE:LICENSE = "GPLv2"
只要不使用空格,您在LICENSE 中指定的许可证可以具有任何名称,因为空格用作许可证名称之间的分隔符。对于标准许可,使用的文件的名称
meta/files/common-licenses/
或SPDXLICENSEMAP中定义的标志名称meta/conf/licenses.conf
。 -
LIC_FILES_CHKSUM:OpenEmbedded 构建系统使用此变量来确保许可证文本未更改。如果有,构建会产生一个错误,它让您有机会找出并纠正问题。
您需要为软件指定所有适用的许可文件。在配置步骤结束时,构建过程将比较文件的校验和以确保文本没有更改。任何差异都会导致包含当前校验和的消息出错。有关如何设置LIC_FILES_CHKSUM变量的更多说明和示例 ,请参阅“跟踪许可证更改”部分。
要确定正确的校验和字符串,您可以在LIC_FILES_CHKSUM变量中列出具有不正确 md5 字符串的相应文件,尝试构建软件,然后注意将报告正确 md5 字符串的结果错误消息。有关其他信息,请参阅“获取代码”部分。
下面是一个假设软件有一个
COPYING
文件的例子:LIC_FILES_CHKSUM = "file://COPYING;md5=xxx"
当您尝试构建软件时,构建系统将产生一个错误并为您提供正确的字符串,您可以将其替换到配方文件中以用于后续构建。
3.3.9依赖
大多数软件包都有一个它们需要的其他软件包的简短列表,称为依赖项。这些依赖主要分为两大类:构建时依赖,构建软件时需要这些依赖;和运行时依赖项,它们需要安装在目标上才能运行软件。
在配方中,您可以使用DEPENDS变量指定构建时依赖 项。尽管存在细微差别,但DEPENDS 中指定的项目应该是其他配方的名称。明确指定所有构建时依赖项很重要。
另一个考虑因素是配置脚本可能会自动检查可选依赖项并在找到这些依赖项时启用相应的功能。如果您希望制作一个更通用的配方(例如,将配方发布在一个层中供其他人使用),而不是硬禁用该功能,您可以使用 PACKAGECONFIG变量来允许启用功能和相应的依赖项并被配方的其他用户轻松禁用。
与构建时依赖项类似,您可以通过变量RDEPENDS指定运行时依赖项,该变量 是特定于包的。所有特定于包的变量都需要将包的名称添加到末尾作为覆盖。由于配方的主包与配方具有相同的名称,并且可以通过${
PN}
变量找到配方的名称 ,因此您可以通过设置 RDEPENDS:${PN}
. 如果包名为${PN}-tools
,则您将设置RDEPENDS:${PN}-tools
,依此类推。
一些运行时依赖将在打包时自动设置。这些依赖项包括任何共享库依赖项(即,如果一个包“example”包含“libexample”,另一个包“mypackage”包含一个链接到“libexample”的二进制文件,那么 OpenEmbedded 构建系统将自动向“mypackage”添加运行时依赖项“示例”)。有关更多详细信息,请参阅Yocto 项目概述和概念手册中的“自动添加的运行时依赖项”部分。
3.3.10配置配方
大多数软件提供了一些在编译前设置构建时配置选项的方法。通常,设置这些选项是通过运行带有选项的配置脚本或通过修改构建配置文件来完成的。
注意
从 Yocto 项目 1.7 版开始,一些打包二进制配置脚本的核心配方现在禁用脚本,因为脚本以前需要容易出错的路径替换。OpenEmbedded 构建系统pkg-config
现在使用,它更加健壮。您可以在 Yocto 项目参考手册*-config
的“禁用二进制配置脚本”部分中找到禁用的脚本列表。
构建时配置的一个主要部分是关于检查构建时依赖项并可能因此启用可选功能。您需要在您的配方的DEPENDS值中为您正在构建的软件指定任何构建时依赖 项,就满足这些依赖项的其他配方而言。您通常可以找到软件文档中描述的构建时或运行时依赖项。
以下列表根据您的软件构建方式提供了注意的配置项目:
-
Autotools:如果您的源文件有
configure.ac
文件,那么您的软件就是使用 Autotools 构建的。如果是这种情况,您只需要修改配置即可。使用 Autotools 时,您的配方需要继承 autotools类,并且您的配方不必包含 do_configure任务。但是,您可能仍需要进行一些调整。例如,您可以设置 EXTRA_OECONF或 PACKAGECONFIG_CONFARGS 以传递特定于配方的任何所需配置选项。
-
CMake:如果您的源文件有
CMakeLists.txt
文件,那么您的软件就是使用 CMake 构建的。如果是这种情况,您只需要修改配置即可。当您使用 CMake 时,您的配方需要继承 cmake类,并且您的配方不必包含 do_configure任务。您可以通过设置EXTRA_OECMAKE来传递特定于配方的任何所需配置选项来进行一些调整 。
注意
如果您需要安装由您正在构建的应用程序提供一个或多个自定义工具链的CMake文件,该文件安装到
${D}${datadir}/cmake/Modules
过程中do_install
。 -
其他:如果您的源文件没有
configure.ac
或CMakeLists.txt
文件,那么您的软件是使用 Autotools 或 CMake 以外的其他方法构建的。如果是这种情况,您通常需要在您的配方中提供一个 do_configure任务,当然,除非没有任何配置。即使您的软件不是由 Autotools 或 CMake 构建的,您仍然可能不需要处理任何配置问题。您需要确定配置是否是必需的步骤。您可能需要修改用于构建的 Makefile 或某些配置文件,以指定必要的构建选项。或者,您可能需要使用适当的选项运行提供的自定义配置脚本。
对于涉及自定义配置脚本的情况,您将运行 并查找需要设置的选项。
./configure --help
一旦配置成功,查看 log.do_configure
文件以确保已启用适当的选项并且不需要将额外的构建时依赖项添加到DEPENDS 始终是一个好习惯。例如,如果配置脚本报告它找到了DEPENDS 中没有提到的东西,或者它没有找到某些所需的可选功能所需的东西,那么您需要将它们添加到DEPENDS。查看日志还可能会发现您不想要的正在检查、启用或两者兼有的项目,或者在DEPENDS 中未找到的项目,在这种情况下,您需要根据需要查看将额外选项传递给配置脚本。有关特定于您正在构建的软件的配置选项的参考信息,您可以查阅其中的命令输出 或查阅软件的上游文档。./configure --help
${S}
3.3.11使用标头与设备接口
如果您的配方构建了一个需要与某些设备通信的应用程序或需要一个 API 到自定义内核中,您将需要提供适当的头文件。在任何情况下都不应修改现有 meta/recipes-kernel/linux-libc-headers/linux-libc-headers.inc
文件。这些标头用于构建libc
并且不得与自定义或特定于机器的标头信息妥协。如果您libc
通过修改的标头进行自定义 ,则所有其他使用的应用程序都会 libc
受到影响。
注意
切勿复制和自定义libc
头文件(即 meta/recipes-kernel/linux-libc-headers/linux-libc-headers.inc
)。
连接到设备或自定义内核的正确方法是使用一个单独的包,它为驱动程序或其他独特的接口提供额外的头文件。这样做时,您的应用程序还负责创建对该特定提供程序的依赖关系。
请考虑以下事项:
-
永远不要修改
linux-libc-headers.inc
。将该文件视为libc
系统的一部分,而不是用于直接访问内核的文件。您应该libc
通过特定libc
电话访问。 -
必须直接与设备对话的应用程序应该自己提供必要的头文件,或者建立对特定于该驱动程序的特殊头文件包的依赖关系。
例如,假设您要修改添加 I/O 控制或网络支持的现有标头。如果修改被少数程序使用,则提供唯一版本的标题很容易并且影响很小。这样做时,请记住上一个列表中的准则。
注意
如果由于某种原因您的更改需要修改 的行为libc
,以及随后系统上所有其他应用程序的行为,请使用 a.bbappend
来修改linux-kernel-headers.inc
文件。但是,请注意不要使更改特定于机器。
考虑您的内核较旧并且您需要较旧的 libc
ABI 的情况。您的配方安装的头文件应该仍然是标准的主线内核,而不是您自己的自定义内核。
当您使用自定义内核头文件时,您需要从STAGING_KERNEL_DIR获取它们 ,该目录包含构建树外模块所需的内核头文件。您的食谱还需要以下内容:
do_configure[depends] += "virtual/kernel:do_shared_workdir"
3.3.12编译
在构建期间,do_compile
任务在获取、解包和配置源之后发生。如果配方do_compile
成功通过,则无需执行任何操作。
但是,如果编译步骤失败,则需要诊断失败。以下是一些导致失败的常见问题。
注意
对于检测到配置文件不正确路径或找不到库/头文件的情况,请确保您使用更强大的pkg-config
. 有关其他信息,请参阅“配置配方”部分中的注释。
-
并行构建失败:这些失败表现为间歇性错误,或报告无法找到应该由构建过程的其他部分创建的文件或目录的错误。即使经过检查,构建失败后文件或目录确实存在,也会发生这种类型的失败,因为构建过程的那部分发生顺序错误。
要解决此问题,您需要满足 Makefile 中缺少的依赖项或生成 Makefile 的任何脚本,或者(作为一种解决方法)将PARALLEL_MAKE设置为空字符串:
PARALLEL_MAKE = ""
有关并行 Makefile 问题的信息,请参阅“调试并行 Make 竞赛”部分。
-
主机路径使用不当:此故障适用于或
nativesdk
仅适用于为目标构建配方。当编译过程在为目标交叉编译时使用了来自主机系统的不正确的头文件、库或其他文件时,就会发生失败。要解决此问题,请检查
log.do_compile
文件以识别正在使用的主机路径(例如/usr/include
、/usr/lib
等),然后添加配置选项、应用补丁或两者都执行。 -
找不到所需的库/头文件:如果构建时依赖项丢失,因为它没有在DEPENDS 中声明 ,或者因为依赖项存在但构建过程用于查找文件的路径不正确并且配置步骤没有检测到它,编译过程可能会失败。对于这些失败中的任何一个,编译过程都会指出无法找到文件。在这些情况下,您需要返回并向配置脚本添加其他选项,并可能向DEPENDS添加其他构建时依赖项。
有时,需要对源应用补丁以确保使用正确的路径。如果您需要指定路径以查找从其他配方暂存到 sysroot 中的文件,请使用 OpenEmbedded 构建系统提供的变量(例如 STAGING_BINDIR、STAGING_INCDIR、STAGING_DATADIR等)。
3.3.13安装
在 期间do_install
,任务将构建的文件及其层次结构复制到将它们在目标设备上的位置镜像的位置。安装过程将文件从${
S}
、 ${
B}
和 ${
WORKDIR}
目录复制 到${
D}
目录,以创建应该出现在目标系统上的结构。
您的软件的构建方式会影响您为确保正确安装软件而必须采取的措施。以下列表描述了根据正在构建的软件使用的构建系统类型,您必须执行哪些安装操作:
-
Autotools 和 CMake:如果您的配方正在构建的软件使用 Autotools 或 CMake,则 OpenEmbedded 构建系统了解如何安装该软件。因此,您不必将
do_install
任务作为配方的一部分。您只需要确保构建的安装部分没有问题即可完成。但是,如果您希望安装 尚未安装的其他文件,您应该使用安装命令的功能来执行此操作 ,如本列表后面的“手册”项目符号项中所述。make install
do_install:append
-
其他(使用 ):您需要 在您的配方中定义一个函数。该函数应该调用 并且可能还需要传入目标目录。您如何通过该路径取决于正在运行的内容的编写方式(例如、 、等等)。
make install
do_install
oe_runmake install
Makefile
DESTDIR=${D}
PREFIX=${D}
INSTALLROOT=${D}
有关使用 的示例配方,请参阅“基于 Makefile 的包”部分。
make install
-
手册:您需要
do_install
在您的配方中定义一个函数。该函数必须首先用于在D下创建目录 。一旦目录存在,您的函数就可以用于将构建的软件手动安装到目录中。install -d
${
}
install
您可以
install
在 https://www.gnu.org/software/coreutils/manual/html_node/install-invocation.html上找到更多信息。
对于不使用 Autotools 或 CMake 的场景,您需要跟踪安装并诊断和修复任何问题,直到一切都正确安装。您需要查看 的默认位置 ${D}
,即${WORKDIR}/image
,以确保您的文件已正确安装。
注意
-
在安装过程中,您可能需要修改一些已安装的文件以适合目标布局。例如,您可能需要将 initscript 中的硬编码路径替换为构建系统提供的变量值,例如替换
/usr/bin/
为${bindir}
. 如果您确实在 期间执行了此类修改do_install
,请确保在复制之后而不是在复制之前修改目标文件。复制后修改确保构建系统可以do_install
在需要时重新执行。 -
oe_runmake install
,可以直接运行,也可以由autotools和 cmake类间接 运行,并行运行。有时,Makefile 可能缺少目标之间的依赖关系,从而导致竞争条件。如果您在 期间遇到间歇性故障 ,您可以通过在配方中添加以下内容来禁用并行 Makefile 安装来解决这些问题:make install
do_install
PARALLEL_MAKEINST = ""
有关其他信息,请参阅PARALLEL_MAKEINST。
-
如果您需要安装一个或多个由您正在构建的应用程序提供的自定义 CMake 工具链文件,请
${D}${datadir}/cmake/Modules
在do_install期间 安装这些文件。
3.3.14开启系统服务
如果你想安装一个服务,这是一个通常在启动时启动并在后台运行的过程,那么你必须在你的配方中包含一些额外的定义。
如果您要添加服务并且未安装服务初始化脚本或服务文件本身,则必须使用do_install:append
函数在您的配方中提供该安装。如果您的配方已经有一个do_install
函数,请在接近结束时更新该函数,而不是添加一个附加do_install:append
函数。
当您为您的服务创建安装时,您需要完成通常由. 换句话说,请确保您的安装排列输出的方式类似于它在目标系统上的排列方式。make install
OpenEmbedded 构建系统支持以两种不同的方式启动服务:
-
SysVinit: SysVinit 是一个系统和服务管理器,用于管理用于控制系统最基本功能的 init 系统。init 程序是 Linux 内核在系统启动时启动的第一个程序。Init 然后控制所有其他程序的启动、运行和关闭。
要使用 SysVinit 启用服务,您的配方需要继承 update-rc.d 类。该类有助于促进在目标上安全地安装包。
您需要 在您的配方中设置 INITSCRIPT_PACKAGES、 INITSCRIPT_NAME和 INITSCRIPT_PARAMS变量。
-
systemd:系统管理守护进程 (systemd) 旨在取代 SysVinit 并提供增强的服务管理。有关 systemd 的更多信息,请参阅位于https://freedesktop.org/wiki/Software/systemd/的 systemd 主页 。
要使用 systemd 启用服务,您的配方需要继承 systemd类。有关 更多信息,请参阅源目录部分中的
systemd.bbclass
文件。
3.3.15包装
成功的打包是 OpenEmbedded 构建系统执行的自动化过程和您需要采取的一些特定步骤的组合。以下列表描述了该过程:
-
拆分文件:该
do_package
任务将配方生成的文件拆分为逻辑组件。即使是生成单个二进制文件的软件也可能仍然有调试符号、文档和其他应该拆分的逻辑组件。该do_package
任务可确保正确拆分和打包文件。 -
运行 QA 检查: inna类在包生成过程中添加了一个步骤,以便 OpenEmbedded 构建系统生成输出质量保证检查。此步骤执行一系列检查,以确保构建的输出没有运行时出现的常见问题。有关这些检查的信息,请参阅该 疯狂类和“ QA错误和警告消息在Yocto计划参考手册”章节。
-
手工检查你的包:在你构建你的软件之后,你需要确保你的包是正确的。检查
${
WORKDIR}/packages-split
目录并确保文件位于您期望的位置。如果发现问题,可以根据需要设置 PACKAGES、 FILES、do_install(:append)
等。 -
将应用程序拆分为多个包:如果您需要将一个应用程序拆分为多个包,请参阅“将应用程序拆分为多个包”部分的示例。
-
安装安装后脚本:有关显示如何安装安装后脚本的示例,请参阅“安装后脚本”部分。
-
标记包架构:根据您的配方正在构建的内容及其配置方式,将生成的包标记为特定于特定机器或将它们标记为根本不特定于特定机器或架构可能很重要.
默认情况下,包适用于与目标机器具有相同架构的任何机器。当配方生成特定于机器的包时(例如, MACHINE值被传递到配置脚本或补丁仅应用于特定机器),您应该通过将以下内容添加到配方中来标记它们:
PACKAGE_ARCH = "${MACHINE_ARCH}"
另一方面,如果配方生成的包根本不包含任何特定于目标机器或架构的内容(例如,简单打包脚本文件或配置文件的配方),您应该使用 allarch类为您添加这是你的食谱:
inherit allarch
在您进行配方的前几次构建时,确保包架构正确并不重要。但是,重要的是要确保您的配方根据配置更改适当地重建(或不重建),并确保您在目标机器上安装了适当的软件包,特别是如果您运行单独的构建以获取更多信息比一台目标机器。
3.3.17使用虚拟供应商
在构建之前,如果您知道多个不同的配方提供相同的功能,您可以使用虚拟提供程序(即virtual/*
)作为实际提供程序的占位符。实际的提供者是在构建时确定的。
使用虚拟提供程序的常见场景是内核配方。假设你有三个核心配方,其 PN值映射到kernel-big
, kernel-mid
和kernel-small
。此外,这些配方中的每一个都以某种方式使用了一个PROVIDES 语句,该语句基本上将自身标识为能够提供 virtual/kernel
. 这是通过内核类的一种方法 :
PROVIDES += "${@ "virtual/kernel" if (d.getVar("KERNEL_PACKAGE_NAME") == "kernel") else "" }"
任何继承kernel
该类的配方都将使用PROVIDES语句来标识该配方能够提供该virtual/kernel
项目。
现在是实际构建映像的时候了,您需要一个内核配方,但是哪个呢?您可以使用PREFERRED_PROVIDER变量配置您的构建以调用您想要的内核配方。例如,考虑x86-base.inc包含文件,它是一个机器(即MACHINE)配置文件。这个包含文件是所有基于 x86 的机器使用linux-yocto
内核的原因。以下是包含文件中的相关行:
PREFERRED_PROVIDER_virtual/kernel ??= "linux-yocto"
PREFERRED_VERSION_linux-yocto ??= "4.15%"
当您使用虚拟提供程序时,您不必“硬编码”配方名称作为构建依赖项。您可以使用 DEPENDS变量来说明构建依赖于virtual/kernel
例如:
DEPENDS = "virtual/kernel"
在构建过程中,OpenEmbedded 构建系统会virtual/kernel
根据PREFERRED_PROVIDER变量选择依赖项所需的正确配方。如果您想使用本节开头提到的小内核,请按如下方式配置您的构建:
PREFERRED_PROVIDER_virtual/kernel ??= "kernel-small"
注意
任何提供virtual/*
最终未通过PREFERRED_PROVIDER选择的项目的配方都不会构建。阻止构建这些配方通常是期望的行为,因为此机制的目的是在互斥的替代提供者之间进行选择。
下面列出了虚拟提供程序的具体示例:
-
virtual/kernel
:提供构建内核映像时要使用的内核配方的名称。 -
virtual/bootloader
:提供构建映像时要使用的引导加载程序的名称。 -
virtual/libgbm
: 提供gbm.pc
。 -
virtual/egl
: 提供egl.pc
并且可能wayland-egl.pc
。 -
virtual/libgl
:提供gl.pc
(即libGL)。 -
virtual/libgles1
:提供glesv1_cm.pc
(即libGLESv1_CM)。 -
virtual/libgles2
:提供glesv2.pc
(即libGLESv2)。