Yocto项目 - 小心Overrides机制还用在Tasks中
在 Yocto 项目中,Overrides 机制(覆盖机制)提供了一种灵活的方法,可以根据特定条件来控制任务和变量的执行。这种机制非常适合在多种硬件平台、不同的配置环境中调整代码的行为,实现代码的复用性和灵活性。然而,如果使用不当,Overrides 机制在特定的任务(Tasks)中可能会导致一些意想不到的效果。因此,了解和掌握 Overrides 机制的工作原理,尤其是在 MACHINE
和 MACHINEOVERRIDES
变量下的应用,是确保 Yocto 项目工作流程顺利运行的关键。
什么是 Overrides 机制?
Overrides 是 Yocto 项目中的一种机制,允许在特定条件下修改或追加任务和变量的值。Overrides 通过覆盖符(override)的方式实现条件化执行。例如,通过 do_install:<override>
或 <variable>:<override>
,可以让任务或变量在满足某种条件时执行特定的变种。这种条件化的能力为在多种硬件平台上开发提供了极大的便利。
MACHINE
和 MACHINEOVERRIDES
变量的作用
在 Yocto 项目中,MACHINE
和 MACHINEOVERRIDES
是两个常用的变量,用于控制和定义覆盖符。理解这两个变量的作用对于在 Yocto 项目中正确使用 Overrides 机制至关重要。
MACHINE
变量
MACHINE
变量用于定义目标硬件平台的名称,不同的硬件平台可能需要不同的配置、任务或软件包。该变量通常在 conf/local.conf
文件中设置,例如:
MACHINE = "raspberrypi4"
这里将目标硬件设置为 raspberrypi4
,使得 BitBake 可以在构建过程中使用与 raspberrypi4
相关的配置。具体来说,通过将 MACHINE
作为覆盖符,我们可以定义特定任务仅在 MACHINE
值匹配时执行。例如:
do_install:raspberrypi4() {
touch ${D}/helloworld_raspberrypi4.c
}
当 MACHINE
设置为 raspberrypi4
时,BitBake 会优先执行 do_install:raspberrypi4()
,而非默认的 do_install()
。
MACHINEOVERRIDES
变量
MACHINEOVERRIDES
是一个层次化的覆盖符变量,用于定义特定平台的条件逻辑。默认情况下,它会包含 MACHINE
的值,并且可以包含更广泛的覆盖范围。例如,如果 MACHINE
设置为 imx8mqevk
,则 MACHINEOVERRIDES
的值可能会是:
MACHINEOVERRIDES =. "arm:imx8mqevk"
这种层次结构使我们可以在更抽象的硬件层次(例如 arm
)或更具体的平台层次(例如 imx8mqevk
)上定义覆盖。例如:
do_install:arm() {
touch ${D}/helloworld_arm.c
}
在这种情况下,如果 MACHINE
是 imx8mqevk
,且没有特定的 do_install:imx8mqevk()
,BitBake 将会执行 do_install:arm()
,从而对所有 ARM 架构的设备应用此任务。通过 MACHINEOVERRIDES
,我们可以在硬件平台的不同层次上灵活控制任务和变量的行为。
示例:基于 MACHINE
和 MACHINEOVERRIDES
控制任务的执行
以下示例展示了如何通过 MACHINE
和 MACHINEOVERRIDES
控制任务执行:
do_install() {
touch ${D}/helloworld1.c
echo "111111"
}
do_install:my-machine() {
touch ${D}/helloworld2.c
echo "222222"
}
do_install:append:my-machine() {
touch ${D}/helloworld3.c
echo "33333"
}
解释
-
do_install()
:这是默认的do_install
任务,适用于所有MACHINE
值。 -
do_install:my-machine()
:此任务覆盖仅在MACHINE="my-machine"
时才会执行。当MACHINE
设置为my-machine
时,这段代码将覆盖do_install()
,生成helloworld2.c
文件并输出222222
。 -
do_install:append:my-machine()
:append
操作符会将代码段追加到do_install:my-machine()
的末尾执行。它表示当MACHINE
为my-machine
时,追加执行do_install()
中定义的内容之外的其他操作,生成helloworld3.c
文件并输出33333
。
构建行为
在 conf/local.conf
中设置:
MACHINE = "my-machine"
当执行构建时,BitBake 会按以下顺序执行 do_install
相关任务:
- 执行
do_install:my-machine()
,创建helloworld2.c
文件并输出222222
。 - 追加执行
do_install:append:my-machine()
的内容,创建helloworld3.c
文件并输出33333
。
这样,默认的 do_install()
不会被执行,因为 do_install:my-machine()
已经覆盖了 do_install()
。
扫描目录名的更改:FILESOVERRIDES 变量
在最新的 Yocto 项目版本中,扫描文件的机制从 OVERRIDES 转变为 FILESOVERRIDES。具体来说,当扫描 SRC_URI
中的文件时,构建系统现在会使用 FILESOVERRIDES
来确定目录名,而不是直接使用 OVERRIDES
。通常情况下,之前在 OVERRIDES
中的值现在也会出现在 FILESOVERRIDES
中。
但是,如果你之前在 OVERRIDES
中添加了额外的值,现在需要将它添加到 FILESOVERRIDES
,除非这些值已经通过 MACHINEOVERRIDES
或 DISTROOVERRIDES
变量自动添加。
示例说明
例如,如果您的构建系统以前依赖 OVERRIDES
中的某个自定义值进行文件路径扫描,现在需要确保该值出现在 FILESOVERRIDES
中,以保持构建系统的文件查找行为不变。
更多关于这一更改的信息,可以参考 Yocto 项目官方文档中的“变量”部分。
总结
在 Yocto 项目中,Overrides 机制(覆盖机制)提供了强大的条件化支持。通过 MACHINE
和 MACHINEOVERRIDES
,我们可以在特定硬件平台上覆盖或追加任务内容,增强配方的复用性和灵活性。同时,最新的 Yocto 项目中引入了 FILESOVERRIDES
以取代 OVERRIDES
用于扫描文件目录,这也为文件查找提供了更为精确的控制。
通过合理使用这些覆盖符和新机制,开发者可以更加轻松地在多平台环境中管理和控制任务的执行,避免了在不同硬件平台下的冲突或重复配置。
相关资源
- Yocto 项目文档 - 变量说明
- BitBake User Manual - Overrides