BitBake
使用 OVERRIDES
来控制在 BitBake
解析食谱和配置文件后去覆盖哪些变量。下面会描述如何把 OVERRIDES
用作条件元数据,并且讨论与 OVERRIDES
有关的关键字展开,同时提供一些示例来帮助理解。
我们可以用OVERRIDES
来有条件地选择变量的特定版本,以及有条件地附加或添加变量的值。
注意:OVERRIDES名称(值)只能使用小写字符。另外,名称中不允许使用下划线,因为它们用于将OVERRIDES与其他名称和变量名称分开。
OVERRIDES
变量是一个冒号字符分隔的列表,该列表包含要满足条件对应的所有替代。因此,如果有一个变量以“arm
”为条件,而“arm
”也在OVERRIDES
中,那么系统就会使用“arm
”特定版本那个变量,而不是无条件版本的变量。这是一个例子: OVERRIDES = "architecture:os:machine"
TEST = "default"
TEST_os = "osspecific"
TEST_nooverride = "othercondvalue"
在此示例中,OVERRIDES
变量列出了三个替代(条件):“architecture
”,“os
”和“machine
”。变量TEST
本身的默认值为“default
”。我们通过将“os
”这个条件附加到变量TEST
(即TEST_os
)来选择特定os
对应的变量版本。
为了更好地理解这一点,请考虑一个实际的示例,该示例假定基于OpenEmbedded
元数据的Linux
内核配方文件。配方文件中的以下几行首先将内核分支变量KBRANCH
设置为默认值,然后根据构建的体系结构有条件地覆盖该值:
KBRANCH = "standard/base"
KBRANCH_qemuarm = "standard/arm-versatile-926ejs"
KBRANCH_qemumips = "standard/mti-malta32"
KBRANCH_qemuppc = "standard/qemuppc"
KBRANCH_qemux86 = "standard/common-pc/base"
KBRANCH_qemux86-64 = "standard/common-pc-64/base"
KBRANCH_qemumips64 = "standard/mti-malta64"
BitBake
还支持根据是否在OVERRIDES
中列出特定项,来对变量值进行追加和前置操作。这是一个例子: DEPENDS = "glibc ncurses"
OVERRIDES = "machine:local"
DEPENDS_append_machine = " libmad"
在此示例中,DEPENDS
变为“glibc ncurses libmad
”。
同样,以基于OpenEmbedded
元数据的内核配方文件为例,以下几行将根据架构体系结构有条件地附加内容到KERNEL_FEATURES
变量:
KERNEL_FEATURES_append = " ${KERNEL_EXTRA_FEATURES}"
KERNEL_FEATURES_append_qemux86=" cfg/sound.scc cfg/paravirt_kvm.scc"
KERNEL_FEATURES_append_qemux86-64=" cfg/sound.scc cfg/paravirt_kvm.scc"
BitBake
支持仅在单个任务期间设置变量。这是一个例子: FOO_task-configure = "val 1"
FOO_task-compile = "val 2"
在这个示例中,FOO
在执行do_configure
任务时值为“val 1
”,在执行do_compile
任务时值为“val 2
” 。
在系统内部,这是通过为了本地数据存储区的do_compile
任务专门添加“task-compile
”条目到OVERRIDES
的值中来实现。
你还可以将此语法与其他组合(例如“ _prepend
”)结合使用,如下示例所示:
EXTRA_OEMAKE_prepend_task-compile = "${PARALLEL_MAKE} "
在最后完成BitBake
数据存储和解析时,将发生关键字扩展。为了更好地理解这一点,请考虑以下示例:
A${B} = "X"
B = "2"
A2 = "Y"
在这种情况下,所有解析完成后,BitBake
扩展${B}
为“2”。在此扩展之前A2
被设置为“Y”,扩展之后A2
最终变为“X”。
尽管前面的解释显示了变量定义的一些不同形式,但是还是很难确切地解释将变量运算符,条件覆盖和无条件覆盖组合在一起时发生的情况。本节介绍了一些常见情况,并解释通常会使用户感到困惑的变量交互案例。
关于overrides
和各种“append
”运算符生效的顺序通常会令人困惑。回想一下,使用"_append"和"_prepend"进行附加或前置操作不会像"+=", “.=”, “=+”, 或者 "=."那样使变量赋值立即生效。考虑以下示例:
OVERRIDES = "foo"
A = "Z"
A_foo_append = "X"
对于这种情况,A
将无条件地设置为“Z
”,并且将“X
”无条件地赋值给变量 A_foo
。由于尚未应用overrides
, 而且因为"_append
"和A
仅等于“Z
”, 所以A_foo
等于“X
”。
但是,应用overrides
会改变结果。由于在OVERRIDES
中列出了“foo
” ,因此有条件的变量A
将被替换为等于“X
”的“foo
”版本。最终A_foo
代替了A
。
下一个示例更改overrides
和append
的顺序:
OVERRIDES = "foo"
A = "Z"
A_append_foo = "X"
对于这种情况,在处理overrides
之前,A
设置为“Z
”,而 A_append_foo
设置为“X
”。但是,一旦应用了对“foo
”的overrides
, A_append
变成“X
”。因此,A
最后值为“ZX
”。请注意,这里没有空格。
下一个示例具有与第一个示例相反的append
和overrides
顺序:
OVERRIDES = "foo"
A = "Y"
A_foo_append = "Z"
A_foo_append = "X"
对于这种情况,在解决任何overrides
之前, A
使用立即扩展将其设置为“Y
”。立即扩展结束后,A_foo
将其设置为“Z
”,然后进一步附加“X
”,将变量设置为“ZX
”。最后,对“foo
”应用overrides
会导致有条件的变量A
变为“ZX
”(即A
被替换为A_foo
)。
最后一个示例混合了一些不同的运算符:
A = "1"
A_append = "2"
A_append = "3"
A += "4"
A .= "5"
对于这种情况,随着BitBake
多次遍历代码,append
操作符的类型会影响分配的顺序。最初,A
由于使用立即数运算符的三个语句将其设置为“1 45
”。完成这些运算后,BitBake
将扩展“_append
”操作。这些操作导致A
的值变为“1 4523
”。