此文为机器辅助翻译,仅供个人学习使用,如有翻译不当之处欢迎指正
原文链接:https://docs.yoctoproject.org/dev-manual/layers.html#
3 了解和创建层
OpenEmbedded 构建系统支持将元数据组织成多个层。层使你能够将不同类型的定制相互隔离。有关 Yocto 项目层模型的介绍性信息,请参阅《Yocto 项目概述和概念手册》中的 “Yocto 项目层模型” 一节。
3.1 创建您自己的层
[!NOTE]
使用 OpenEmbedded 构建系统创建自己的层非常容易,因为 Yocto 项目自带了能加快层创建速度的工具。本节介绍手动创建层的步骤,以便你能更好地理解。有关层创建工具的信息,请参阅《Yocto 项目板级支持包(BSP)开发者指南》中的 “使用 bitbake-layers 脚本创建新的 BSP 层” 部分,以及本手册后文 “使用 bitbake-layers 脚本创建通用层” 部分。
请按照以下一般步骤,在不使用工具的情况下创建自己的层:
1.检查现有层:在创建新层之前,你应确认是否已有其他人创建了包含你所需元数据的层。你可以查看 OpenEmbedded 元数据索引,获取可在 Yocto 项目中使用的 OpenEmbedded 社区层列表。你可能会找到与你需求相同或相近的层。
2.创建目录:为你的层创建目录。创建层时,确保在与 Yocto 项目源目录(例如克隆的 poky 存储库)无关的区域创建该目录。
虽然并非严格要求,但建议在目录名称前加上 “meta-
” 字
meta-mylayer
meta-GUI_xyz
meta-mymachine
除极少数情况外,层的名称遵循以下形式:
meta-root_name
遵循此层命名约定,日后在工具、组件或变量 “假定” 你的层名称以 “meta-
” 开头时,可为你省去麻烦。一个明显的例子是在配置文件中,如下一步所示,没有 “meta-
” 字符串的层名称会被追加到配置中使用的几个变量中。
3.创建层配置文件:在新创建的层文件夹内,你需要创建一个 conf/layer.conf
文件。最简单的方法是选取一个现有的层配置文件,将其复制到你的层的 conf 目录中,然后根据需要进行修改。
Yocto 项目源存储库中的 meta-yocto-bsp/conf/layer.conf
文件展示了所需的语法。对于你的层,你需要将 “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 变量时,可以用这个版本号指定该层的精确版本作为依赖项。
-
LAYER依赖: 列出该层所依赖的所有层(如果有的话)。
-
LAYERSERIES_COMPAT: 列出与当前层版本兼容的 Yocto 项目版本。这个变量是表明特定层是否为最新版本的一种有效方式。
[!NOTE]
层不一定只包含配方文件.bb 或追加文件.bbappend
。通常,开发者使用bitbake-layers create-layer
命令创建层。请参阅 “使用 bitbake-layers 脚本创建通用层”,该部分解释了layer.conf
文件是如何从位于meta/lib/bblayers/templates/layer.conf
的模板创建的。实际上,layer.conf
中设置的变量都不是强制的,除非存在BBFILE_COLLECTIONS
变量。在这种情况下,还必须定义LAYERSERIES_COMPAT
和BBFILE_PATTERN
变量。
4.添加内容:根据层的类型添加相应内容。如果该层为某机器添加支持,就在层内的 conf/machine/
文件中添加机器配置。如果该层添加发行版策略,就在层内的 conf/distro/
文件中添加发行版配置。如果该层引入新配方,就将所需的配方放在层内的 recipes-*
子目录中。
[!NOTE]
有关符合 Yocto 项目规范层的层次结构说明,请参阅《Yocto 项目板级支持包(BSP)开发者指南》中的 “示例文件系统布局” 章节。
5.可选兼容性测试:如果您希望您的层或使用该层的应用程序有权使用 Yocto Project 兼容性标志,请执行申请兼容性的步骤。有关更多信息,请参见 “确保您的层与 Yocto Project 兼容” 部分。
3.2 创建层时的最佳实践
为了创建更易于维护且不会影响其他机器构建的层,您应考虑以下建议:
1.避免在配置中 “覆盖” 其他层的完整配方:换言之,不要将整个配方复制到您的层中再进行修改,而应使用追加文件(.bbappend
)仅覆盖原始配方中需要修改的部分。
2.避免重复包含文件:对每个使用包含文件的配方使用追加文件(.bbappend
)。或者,如果您引入需要包含文件的新配方,请使用相对于原始层目录的路径引用该文件。例如,使用 require recipes-core/package/file.inc
而非 require file.inc
。如果需要覆盖包含文件,可能表明该文件所在层存在不足。此时,您应尝试解决该不足,而非直接覆盖包含文件。例如,您可以联系包含文件的维护者,添加可轻松覆盖所需部分的变量。
3.合理构建层结构:在追加文件中正确使用覆盖功能,并将机器特定文件放置在层内,可确保构建不会使用错误的元数据,从而避免对其他机器的构建产生负面影响。以下是一些示例:
-
修改变量以支持不同机器:假设您有一个名为
meta-one
的层,用于支持构建机器 “one
”。为此,您使用名为base-files.bbappend
的追加文件,并通过修改 DEPENDS 变量创建对 “foo
” 的依赖:DEPENDS = "foo"
该依赖会在包含
meta-one
层的任何构建中生效。但您可能不希望所有机器都有此依赖。例如,当构建机器 “two
” 且bblayers.conf
文件包含meta-one
层时,机器 “two” 的base-files
也会依赖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"
-
将机器特定文件放置在特定目录:当基础配方(如
base-files.bb
)包含指向某文件的SRC_URI
语句时,可通过追加文件使构建使用自定义版本的文件。例如,在层meta-one/recipes-core/base-files/base-files.bbappend
中,可通过FILESEXTRAPATHS
预添加路径:FILESEXTRAPATHS:prepend := "${THISDIR}/${BPN}:"
只要将机器 “one” 的特定文件放置在
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” 时生效,还能加快构建过程中的文件定位速度。总之,您需要将 SRC_URI 引用的所有文件放置在层内的机器特定子目录中,以便将这些文件限制在特定机器的构建中。
4.申请 Yocto 项目兼容性的步骤:如果您希望您的层或使用该层的应用程序有权使用 Yocto 项目兼容性标志,请执行以下申请兼容性的步骤。有关更多信息,请参阅 “确保您的层与 Yocto 项目兼容” 部分。
5.遵循层命名约定:将自定义层存储在采用 meta-layer_name
格式的 Git 存储库中。
6.在本地分组层:将您的存储库与从源目录克隆的其他 meta
目录并列存放。
3.3 确保您的层与 Yocto Project 兼容
当您创建用于 Yocto 项目的层时,确保该层与现有的 Yocto 项目层良好交互(即该层与 Yocto 项目兼容)是有益的。确保兼容性可使该层易于被 Yocto 项目社区的其他成员使用,并可能允许您使用 Yocto 项目兼容标志。
[!NOTE]
只有 Yocto 项目成员组织允许使用 Yocto 项目兼容标志,该标志不供一般用途。有关如何成为 Yocto 项目成员组织的信息,请访问 Yocto 项目网站。
Yocto 项目兼容性计划包括一个层申请流程,该流程要求为您的层和应用程序使用 Yocto 项目兼容标志的权限。该流程包括两部分:
-
成功通过脚本检查(yocto-check-layer):运行该脚本针对您的层进行测试,根据层在实际应用中的工作经验和已知缺陷场景对其进行约束测试。成功通过脚本测试(获得 “PASS” 结果)是兼容性注册的必要条件。
-
完成申请接受表格:您可以在https://www.yoctoproject.org/compatible-registration/找到该表格。
要获得使用标志的权限,您需要满足以下条件:
-
能够在表格中勾选 “运行脚本针对您的层测试获得‘PASS’” 的选项。
-
对表格中的问题回答 “是”,或对任何回答 “否” 的问题提供可接受的解释。
-
是 Yocto 项目成员组织。
本节其余部分将介绍注册表格和 yocto-check-layer
脚本的相关信息。
3.3.1 Yocto 项目兼容性计划申请
使用此表格申请您的层通过审核。申请成功后,您可以在您的层及使用该层的应用程序中使用 Yocto 项目兼容性标志。
要访问该表格,请使用此链接:https://www.yoctoproject.org/compatible-registration。请按照表格上的说明完成申请。
申请包含以下部分:
- 联系信息:按字段要求提供您的联系信息。除个人信息外,请说明您的层所兼容的 Yocto 项目发布版本。
- 验收标准:对清单中的每个项目回答 “是” 或 “否”。表格底部提供空间,用于对回答 “否” 的项目进行解释。
- 建议:回答有关 Linux 内核使用和构建成功的问题。
3.3.2 yocto-check-layer
脚本
yocto-check-layer
脚本为您提供了一种评估层与 Yocto 项目兼容性的方法。如前所述,您应在使用表格申请兼容性之前运行此脚本。您需要获得 “PASS” 结果,才能成功处理申请表格。
脚本将测试分为三个领域: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
层是否具有machine
配置。 -
bsp.test_bsp_no_set_machine
:测试以确保BSP
层不会 设置添加图层时的计算机。 -
bsp.test_machine_world
:验证无论选择哪台机器,bitbake world
命令均能正常工作。 -
bsp.test_machine_signatures
:验证该建筑物的 特定计算机仅影响特定于 那台机器。 -
distro.test_distro_defines_distros
:测试DISTRO
层是否具有distro
配置。 -
distro.test_distro_no_set_distros
:测试以确保DISTRO
层 在添加图层时不设置分布。
3,4 启用您的层
在 OpenEmbedded 构建系统使用新层之前,需要先启用它。启用层的方法很简单,只需将层的路径添加到构建目录中的 conf/bblayers.conf
文件的 BBLAYERS
变量中即可。
以下示例展示如何启用新的 meta-mylayer
层(注意新层位于官方 poky 仓库之外,即您之前检出的路径):
# 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/mystuff/meta-mylayer \
"
BitBake 会按照 conf/bblayers.conf
文件中 BBLAYERS
变量的顺序从上至下解析每个 conf/layer.conf
文件。在处理每个 conf/layer.conf
文件时,BitBake 会将该层包含的配方、类和配置添加到源目录中。
3,5 用您的层追加其他层的元数据
向其他配方追加元数据的文件称为 BitBake 追加文件(.bbappend
文件),而被追加元数据的对应配方文件以.bb 为后缀。
您可以在自己的层中使用.bbappend
文件向其他层的配方添加或修改内容,而无需将目标层的配方复制到自己的层中。.bbappend
文件存放在您的层中,而被追加元数据的主.bb 配方文件则位于其他层中。
能够向现有配方追加信息不仅可以避免重复,还能自动将来自不同层的配方更改应用到您的层中。如果直接复制配方,则必须在发生更改时手动合并变更。
创建追加文件时,必须使用与对应配方文件相同的根名称。例如,追加文件 someapp_3.1.bbappend
必须应用于 someapp_3.1.bb
。这意味着原始配方和追加文件的文件名是特定于版本号的。如果对应配方因更新版本而重命名,你必须同时重命名并可能更新相应的.bbappend
文件。
在构建过程中,如果 BitBake 检测到某个.bbappend
文件没有匹配名称的对应配方,就会在启动时显示错误。处理这些错误的最佳实践是将.bbappend
重命名为与原始配方版本匹配的名称。这也让你有机会检查该.bbappend
是否仍然适用于配方的新版本。
另一种方法是在.bbappend
文件名中使用 % 字符。例如,要向 someapp 配方的每个 6.* minor
版本追加信息,可以创建 someapp_6.%.bbappend
文件。这样,只有当 someapp 配方进行主版本更新时才会触发错误。
最后,处理这些错误的另一种方法是使用变量 BBMASK,尤其是在无法修改.bbappend
的情况下。
3.5.1 使用图层叠加文件
以源目录中的主 formfactor 配方和对应的 formfactor 追加文件为例。以下是主 formfactor 配方,名为 formfactor_0.0.bb
,位于 “meta
” 层的 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 构建系统在构建过程中从何处查找文件。
以下是来自名为 meta-raspberrypi 的树莓派 BSP 层的追加文件,文件名为 formfactor_0.0.bbappend
,位于层内的 recipes-bsp/formfactor
目录下:
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
默认情况下,构建系统使用FILESPATH
变量定位文件。此追加文件通过设置FILESEXTRAPATHS
变量扩展了搜索路径。在.bbappend 文件中设置该变量是向构建系统用于查找文件的搜索路径添加目录的最可靠且推荐的方法。
此示例中的语句将目录扩展为包含${THISDIR}/${PN}
,该路径解析为追加文件所在目录中的 formfactor 目录(即 meta-raspberrypi/recipes-bsp/formfactor
)。这意味着您必须设置支持的目录结构,以包含将从该层引入的任何文件或补丁。
由于引用了THISDIR
,使用立即扩展赋值运算符:=
非常重要。末尾的冒号字符也很重要,它确保列表中的项保持以冒号分隔。
[!NOTE]
BitBake 会自动定义THISDIR
变量,切勿自行设置该变量。在FILESEXTRAPATHS
中使用:prepend
可确保您的路径在最终列表中先于其他路径被搜索。此外,并非所有追加文件都会添加额外文件。许多追加文件仅用于添加构建选项(如 systemd),此时追加文件甚至无需使用
FILESEXTRAPATHS
语句。
此.bbappend
文件的最终效果是:在树莓派(其rpi
会存在于 OVERRIDES 列表中)上,构建系统将在 do_fetch
阶段使用文件 meta-raspberrypi/recipes-bsp/formfactor/formfactor/rpi/machconfig
,并且 do_instal
l 中的非零文件大小检查将返回 true
,该文件将被安装。
3.5.2 使用您的层安装额外文件
再举一例,以源目录中的主 xserver-xf86-config
配方和对应的 xserver-xf86-config
追加文件为例。以下是主 xserver-xf86-config
配方,文件名为 xserver-xf86-config_0.1.bb
,位于 “meta
” 层的 meta/recipes-graphics/xorg-xserver
目录下:
SUMMARY = "X.Org X server configuration file"
HOMEPAGE = "http://www.x.org"
SECTION = "x11/base"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
PR = "r33"
SRC_URI = "file://xorg.conf"
S = "${WORKDIR}"
CONFFILES:${PN} = "${sysconfdir}/X11/xorg.conf"
PACKAGE_ARCH = "${MACHINE_ARCH}"
ALLOW_EMPTY:${PN} = "1"
do_install () {
if test -s ${WORKDIR}/xorg.conf; then
install -d ${D}/${sysconfdir}/X11
install -m 0644 ${WORKDIR}/xorg.conf ${D}/${sysconfdir}/X11/
fi
}
以下是来自名为 meta-raspberrypi
的树莓派 BSP 层的追加文件,文件名为 xserver-xf86-config_%.bbappend
,位于该层的 recipes-graphics/xorg-xserver
目录下。
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI:append:rpi = " \
file://xorg.conf.d/98-pitft.conf \
file://xorg.conf.d/99-calibration.conf \
"
do_install:append:rpi () {
PITFT="${@bb.utils.contains("MACHINE_FEATURES", "pitft", "1", "0", d)}"
if [ "${PITFT}" = "1" ]; then
install -d ${D}/${sysconfdir}/X11/xorg.conf.d/
install -m 0644 ${WORKDIR}/xorg.conf.d/98-pitft.conf ${D}/${sysconfdir}/X11/xorg.conf.d/
install -m 0644 ${WORKDIR}/xorg.conf.d/99-calibration.conf ${D}/${sysconfdir}/X11/xorg.conf.d/
fi
}
FILES:${PN}:append:rpi = " ${sysconfdir}/X11/xorg.conf.d/*"
基于前面的示例,我们再次设置FILESEXTRAPATHS
变量。在这种情况下,当rpi
出现在OVERRIDES
列表中时,我们还使用SRC_URI
列出要使用的额外源文件。然后,do_install
任务将检查是否设置了额外的MACHINE_FEATURES
,如果设置了,这些额外文件将被安装。这些额外文件在FILES
中列出,以便进行打包。
3,6 层的优先级设置
每个层都被分配一个优先级值。当多个层中存在同名配方文件时,优先级值决定哪个层的文件优先生效 —— 优先级数值更高的层中的配方文件将优先被使用。优先级值还会影响同一配方的多个.bbappend
文件的应用顺序。你可以手动指定优先级,也可以让构建系统根据层的依赖关系自动计算。
若要手动指定层的优先级,可使用BBFILE_PRIORITY
变量并追加层的根名称,例如:
BBFILE_PRIORITY_mylayer = "1"
[!NOTE]
- 高优先级层中版本号(PV)较低的配方可能会覆盖低优先级层的高版本配方。
- 当前层优先级不影响.conf 或.bbclass 文件的优先级顺序,BitBake 的未来版本可能会解决这一问题。
3.6.1 通过层提供全局级配置
创建层时,若需要定义在构建环境中全局生效的配置(当该层参与构建时),可利用层的 layer.conf 文件 —— 该文件是全局影响构建系统的配置文件,适合此类场景。
[!Warning]
从 layer.conf 文件中无条件提供全局级配置并非最佳实践,应尽量避免。因此,下文 “有条件地通过层提供全局级配置” 部分将说明如何仅在满足特定条件时通过 layer.conf 文件提供配置。
例如,若你的层提供一个名为 linux-custom 的 Linux 内核配方,可能需要将PREFERRED_PROVIDER_virtual/kernel
指向该配方:
PREFERRED_PROVIDER_virtual/kernel = "linux-custom"
此配置可定义在 layer.conf 文件中。若该层在 BBLAYERS 列表中位于最后一位,它将覆盖之前对PREFERRED_PROVIDER_virtual/kernel
的赋值(除非后续解析的配置文件,如机器或发行版配置文件中另有设置)。
3.6.1.1 有条件地通过层提供全局级配置
在某些情况下,你的层可能仅在其提供的某些功能启用时才提供全局配置。由于 layer.conf 文件在解析流程的早期阶段被解析,此时 DISTRO_FEATURES 和 MACHINE_FEATURES 变量尚未可用,因此无法基于这些变量声明条件赋值。以下方法展示了如何通过使用 USER_CLASSES 变量和条件 require 命令绕过这一限制。
在以下步骤中,假设我们的层名为 meta-mylayer,且该层定义了一个名为 mylayer-kernel 的自定义发行版功能。我们将仅在 DISTRO_FEATURES 包含 mylayer-kernel 功能时设置内核的 PREFERRED_PROVIDER 变量:
1.在 meta-mylayer/conf/distro/include/ 目录下创建一个包含文件,例如命名为 mylayer-kernel-provider.inc 的文件,用于将内核提供方设置为 linux-custom:
PREFERRED_PROVIDER_virtual/kernel = "linux-custom"
2.在 layer.conf 中提供该包含文件的路径:
META_MYLAYER_KERNEL_PROVIDER_PATH = "${LAYERDIR}/conf/distro/include/mylayer-kernel-provider.inc"
1.在 meta-mylayer/classes-global/ 目录下创建一个新类,例如命名为 meta-mylayer-cfg.bbclass 的类。使用 layer.conf 中定义的 META_MYLAYER_KERNEL_PROVIDER_PATH 变量,有条件地引用上述 mylayer-kernel-provider.inc 文件:
require ${@bb.utils.contains('DISTRO_FEATURES', 'mylayer-kernel', '${META_MYLAYER_KERNEL_PROVIDER_PATH}', '', d)}
有关 bb.utils.contains 函数的详细信息,请参阅 lib/bb/utils.py 中的定义。
[!NOTE]
如果 bb.utils.contains 函数返回空字符串,require 命令将不会报错。
1.返回 layer.conf 文件,将 meta-mylayer-cfg 类添加到 USER_CLASSES 变量中:
USER_CLASSES:append = " meta-mylayer-cfg"
这会将 meta-mylayer-cfg 类添加到全局继承的类列表中。由于 require 命令在 meta-mylayer-cfg.bbclass 中是有条件的,因此即使继承了该类,除非通过 DISTRO_FEATURES 启用 mylayer-kernel 功能,否则该类不会产生任何效果。
这种技术也可以通过相同的步骤用于机器特性(Machine features)。虽然不是强制性的,但建议将与发行版特性(DISTRO_FEATURES)相关的包含文件放在您的层的conf/distro/include
目录中,而将与机器特性(MACHINE_FEATURES)相关的包含文件放在您的层的conf/machine/include
目录中。
3.7 管理层
您可以使用 BitBake 层管理工具 bitbake-layers 来查看多层项目中配方的结构。通过生成报告配置层的路径、优先级、.bbappend
文件及其适用配方的输出,有助于发现潜在问题。
如需获取 BitBake 层管理工具的帮助,可使用以下命令:
$ bitbake-layers --help
以下列表描述了可用的命令:
-
help:
显示常规帮助或指定命令的帮助。 -
show-layers:
显示当前配置的层。 -
show-overlayed:
列出被覆盖的配方。当另一个优先级更高的层中存在同名配方时,该配方即被覆盖。 -
show-recipes:
列出可用配方及其所属的层。 -
show-appends:
列出.bbappend
文件及其对应的配方文件。 -
show-cross-depends:
列出跨层的配方依赖关系。 -
add-layer:
向bblayers.conf
中添加一个层。 -
remove-layer:
从bblayers.conf
中移除一个层。 -
flatten:
将层配置扁平化到一个独立的输出目录中。扁平化层配置会构建一个 “扁平化” 目录,其中包含所有层的内容,移除所有被覆盖的配方,并将所有.bbappend
文件合并到对应配方中。您可能需要手动清理扁平化后的层,注意以下事项:-
非配方文件(如补丁)会被覆盖,flatten 命令会对此类文件显示警告。
-
层
.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
:从层索引中查找层依赖关系。 -
save-build-conf
:将当前活动的构建配置(conf/local.conf
、conf/bblayers.conf
)作为模板保存到一个层中。该模板后续可通过 TEMPLATECONF 用于设置构建环境。有关保存和使用配置模板的信息,请参阅 “创建自定义模板配置目录”。 -
create-layer
:创建基本层。 -
create-layers-setup
:写出一个配置文件和 / 或脚本,用于复制当前构建中各层的目录结构和版本。更多信息请参阅 “保存和恢复层设置”。
3.8 使用 bitbake-layers 脚本创建通用层
使用 create-layer 子命令的 bitbake-layers 脚本可简化新通用层的创建流程。
[!NOTE]
有关 BSP 层的信息,请参阅《Yocto 项目板级特定(BSP)开发者指南》中的 “BSP 层” 部分。
若要在 OpenEmbedded 构建系统中使用某个层,需将该层添加到 bblayers.conf 配置文件中。更多信息请参阅 “使用 bitbake-layers 脚本添加层” 部分。
该脚本使用此子命令的默认模式会创建一个包含以下内容的层:
-
层优先级为 6。
-
一个包含
layer.conf
文件的conf
子目录。 -
一个
recipes-example
子目录,其中包含一个名为example
的子目录,该子目录下有一个example.bb
配方文件。 -
一个
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 选项,或在脚本创建层后编辑 conf/layer.conf 中的 BBFILE_PRIORITY 值。此外,如果您希望为示例配方文件指定非默认名称,可以使用 --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.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
将该层添加到该文件中可使构建系统在构建过程中定位到该层。
[!NOTE]
在构建过程中,OpenEmbedded 构建系统会按列表从上到下的顺序查找各层。
3,10 保存和恢复层设置
当你通过正确的层集合完成一次成功的构建后,将层设置(包括层名称、来源仓库及其 SCM 版本)捕获到配置文件中会非常有用,这样后续可以在不同机器上轻松复现该设置。操作步骤如下:
$ bitbake-layers create-layers-setup /srv/work/alex/meta-alex/
NOTE: Starting bitbake server...
NOTE: Created /srv/work/alex/meta-alex/setup-layers.json
NOTE: Created /srv/work/alex/meta-alex/setup-layers
该工具需要一个参数指定输出位置,生成的内容包括 JSON 格式的层配置文件和一个 setup-layers 脚本。后者可利用该配置在不同位置或主机上恢复层设置。参数可以指向自定义层(该层将被视为需先检出的 “引导层”)或完全独立的路径。
复现层设置的步骤如下:
1.克隆引导层或其他仓库,获取 JSON 配置文件和配套的 setup-layers 脚本。
2.直接运行脚本(无需参数)。
alex@Zen2:/srv/work/alex/my-build$ meta-alex/setup-layers
Note: not checking out source meta-alex, use --force-bootstraplayer-checkout to override.
Setting up source meta-intel, revision 15.0-hardknott-3.3-310-g0a96edae, branch master
Running 'git init -q /srv/work/alex/my-build/meta-intel'
Running 'git remote remove origin > /dev/null 2>&1; git remote add origin git://git.yoctoproject.org/meta-intel' in /srv/work/alex/my-build/meta-intel
Running 'git fetch -q origin || true' in /srv/work/alex/my-build/meta-intel
Running 'git checkout -q 0a96edae609a3f48befac36af82cf1eed6786b4a' in /srv/work/alex/my-build/meta-intel
Setting up source poky, revision 4.1_M1-372-g55483d28f2, branch akanavin/setup-layers
Running 'git init -q /srv/work/alex/my-build/poky'
Running 'git remote remove origin > /dev/null 2>&1; git remote add origin git://git.yoctoproject.org/poky' in /srv/work/alex/my-build/poky
Running 'git fetch -q origin || true' in /srv/work/alex/my-build/poky
Running 'git remote remove poky-contrib > /dev/null 2>&1; git remote add poky-contrib ssh://git@push.yoctoproject.org/poky-contrib' in /srv/work/alex/my-build/poky
Running 'git fetch -q poky-contrib || true' in /srv/work/alex/my-build/poky
Running 'git checkout -q 11db0390b02acac1324e0f827beb0e2e3d0d1d63' in /srv/work/alex/my-build/poky
[!NOTE]
这也适用于更新现有的代码检出。
[!NOTE]
该脚本独立运行,仅要求构建机器上安装 python3 和 git。
[!NOTE]
create-layers-setup 和 setup-layers 脚本提供了多个自定义行为的附加选项,欢迎通过 --help 命令行参数了解详情。