各位。
我一直在研究 yocto 构建过程,我注意到以下结构的用法:
PN = "${@bb.parse.vars_from_file(d.getVar('FILE', False),d)[0] or 'defaultpkgname'}"
我知道 ${} 表示变量扩展,并且 grep 命令显示函数“vars_from_file”位于 bitbake/lib/bb/parse/__init__.py。
我想了解这个变量扩展是如何工作的,所以我探索了 bitbake 文件并发现:
oe-init-build-env 调用 oe-buildenv-internal,最后一个将 PYTHONPATH 设置为 bitbake/lib。
我推断 bitbake 使用 PYTHONPATH 来搜索函数 vars_from_file
我不明白的是:
${@bb.parse.__init__.vars_from_file(d.getVar('FILE', False),d)[0] or 'defaultpkgname'}
而不是"${@bb.parse.vars_from_file(d.getVar('FILE', False),d)[0] or 'defaultpkgname'}"
有人可以帮助我理解它们吗?
@ 符号用于内联 python 变量扩展,它基本上表明您将调用一个函数并扩展其结果,通常将其分配给一个变量,在您的情况下:
PN = "${@bb.parse.vars_from_file(d.getVar('FILE', False),d)[0] or 'defaultpkgname'}"
它将来自 bitbake python 模块解析的函数 vars_from_file 的结果分配给 PN(包名称),该函数位于 bitbake/lib/bb/parse/
与任何其他 Python 模块一样,它会自动加载 init.py 并在导入时可以访问这些函数。
这些函数的特别之处在于它们可以访问 bitbake 的数据字典,称为“d”。
AFAIC 这是 bitbake 特有的。
我在gnu网站上查了一下,结构体开头并没有“@”的应用。
“结构”称为“参数扩展”:https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
bitbake 配方中的这种类型的变量扩展仅适用于bitbake吗?
shell 脚本在由 shell 执行之前经过大量预处理,其中包括扩展
${@...}
语法。
文档中没有明确提及这一点。
你可以在bitbake的代码中找到血淋淋的细节:
exec_func_shell()
:将 python 函数写入文件,由 shell 执行:https://github.com/yoctoproject/poky/blob/kirkstone/bitbake/lib/bb/build.py#L407
emit_func()
:代码写出之前的预处理:
https://github.com/yoctoproject/poky/blob/kirkstone/bitbake/lib/bb/data.py#L213
emit_var()
:获取一个“变量”(bitbake 中 shell 函数的代码是来自数据存储的“变量”,应用扩展:
https://github.com/yoctoproject/poky/blob/kirkstone/bitbake/lib/bb/data.py#L118
[...]
这是 ${@...}
实际展开的地方):
https://github.com/yoctoproject/poky/blob/kirkstone/bitbake/lib/bb/data_smart.py#L452
在执行之前,它会应用于 bitbake 配方中的“shellscript”代码。
为了奖励积分,bitbake 甚至在 shell 执行之前使用 python 解析器在内部解析 shell 函数,以跟踪依赖关系: https://github.com/yoctoproject/poky/blob/kirkstone/bitbake/lib/bb/codeparser.py#L343