By: fu linux
E-mail: fulinux@sina.com
Blog: https://blog.csdn.net/fulinus
喜欢的盆友欢迎点赞和订阅!
你的喜欢就是我写作的动力!
开篇简述
bitbake工具可以和其他语言一样可以使用函数来做相应的功能和任务,比如:
...
do_configure()
do_compile()
do_install()
...
- 1
- 2
- 3
- 4
- 5
bitbake支持的函数类型有
- shell函数:用shell脚本编写的函数,直接作为函数或任务执行,或同时作为函数和任务执行。它们也可以被其他shell函数调用;
- BitBake风格的python函数:用Python编写并由BitBake或其他Python函数使用bb.build.exec_func()执行的函数;
- Python函数:用Python编写并由Python执行的函数;
- 匿名(Anonymous)的Python函数:Python函数在解析过程中自动执行;
shell函数
这样的函数形如:
some_function () {
echo "Hello World"
}
- 1
- 2
- 3
在recipe或class文件中创建这些类型的函数时,需要遵循shell编程规则。脚本由/bin/sh执行,它可能不是bash shell,但可能是dash之类的东西,所以不应该使用特定于bash的脚本
可以在函数后加上_append或者_prepend关键词来规定执行顺序。
我们在前面 yocto-第4篇-创建自己的layer 文章中创建的example_1.0.bb文件:
poky]$ vim meta-mylayer/recipes-example/example/example_0.1.bb
...
do_foo() {
bbplain first
fn
}
fn_prepend() {
bbplain second
}
fn() {
bbplain third
echo "third 3th"
}
do_foo_append() {
bbplain fourth
}
addtask foo
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
重点看下上面4个函数是执行顺序,运行结果如下:
poky]$ source oe-init-build-env
build]$ bitbake example -c cleanall
build]$ bitbake example -c foo
...
first
second
third
fourth
...
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
BitBake风格的Python函数
这个类型的函数通常是用Python语言写的,通过bitbake或者其他Python函数使用bb.build.exec_func()调用执行。
实例如下:
python do_some_python_function () {
d.setVar("TEXT", "Hello World")
print d.getVar("TEXT")
}
- 1
- 2
- 3
- 4
Python依赖的"bb"和"os" Python模块已经自动导入了。
看上面的例子中TEXT被赋值为“Hello World”字符串,在引用的时候不是用${TEXT},而是用d.getVar(“TEXT”)。这点差异记住。
其实在poky/meta-mylayer/recipes-example/example/example_0.1.bb文件中已经有用到Python函数的例子了,如下:
python do_compile() {
bb.plain("***********************************************");
bb.plain("* *");
bb.plain("* Example recipe created by bitbake-layers *");
bb.plain("* *");
bb.plain("***********************************************");
}
addtask compile
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
继续在这个example_0.1.bb文件中,举个例子,同时熟悉Tasks的内容:
python do_printdate() {
DATE = "${@time.strftime('%Y%m%d', time.gmtime())}"
bb.plain(d.getVar("DATE"))
}
addtask printdate after do_fetch before do_build
- 1
- 2
- 3
- 4
- 5
- 6
这里面用到了获取时间,以及打印时间的一些技巧,最后运行的结果如下:
build]$ bitbake example -c cleanall
build]$ bitbake example
...
WARNING: python should use 4 spaces indentation, but found tabs in example_0.1.bb, line 38
**20210222**
...
- 1
- 2
- 3
- 4
- 5
- 6
日期是20210222,这个字符串对于某些软件使用时间做版本还是很有帮助的,直接定义某个C宏,让其作为版本,而不用每次修改版本信息很有帮助。函数也可以用_append或者_prepend后缀来规定执行顺序。
你学费了吗?
Python函数
这些函数是用Python编写的,由其他Python代码执行。
直接上栗子:
poky/meta-mylayer/recipes-example/example/example_0.1.bb
...
def get_depends(d):
if d.getVar('SOMECONDITION'):
return "libABC"
else: #there is ":"
return "libXYZ"
SOMECONDITION = "1"
DEPENDS = "${@get_depends(d)}"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
我们知道在执行某个recipe时,会首先执行其依赖的recipe,用DEPENDS关键词,那么这里是什么呢?
这个例子用到了一个条件变量SOMECONDITION,当其存在时,返回“libABC”,不存在时返回“libXYZ”。
执行结果如下:
build]$ bitbake example
- 1
上面因为没有libABC_*.bb recipe所以会出现依赖关系不存在的情况,就报错了。
相反如果我们将
SOMECONDITION = ""
- 1
设置为空,运行结果如下:
同理,libXYZ也不存在,所以也报错了。
报错了可能这个例子后期就是一个麻烦,这里我们替换其中一个依赖,改为leanyocto项目。如下:
def get_depends(d):
if d.getVar('SOMECONDITION'):
return "learnyocto"
else: #there is ":"
return "libXYZ"
SOMECONDITION = "1"
DEPENDS = "${@get_depends(d)}"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
条件存在时依赖learnyocto项目,我们先将learnyocto recipe清空,然后在构建build的时候就可以看到learnyocto执行的过程了:
build]$ bitbake learnyocto -c cleanall
build]$ bitbake example
- 1
- 2
自己看运行过程
Python函数特点
- 可以带参数,例如get_depends(d)
- BitBake数据存储不是自动可用的。因此,必须将其作为参数传递给函数, 就是上面参数d
- “bb"和"os” Python模块自动可用,不需要导入它们。
给我点个赞呗!