写在前面
这是《BitBake使用攻略》系列文章的第三篇,主要讲解BitBake的基本语法。由于此篇的实验依赖于第一篇的项目,建议先将HelloWorld项目完成之后再食用此篇为好。
第一篇的链接在这:BitBake使用攻略--从HelloWorld讲起。
1. BitBake中的任务
对于BitBake,运行一个菜谱(recipe)其实运行的就是这个菜谱中的任务。任务可以说是BitBake的执行单元,它仅仅出现在菜谱和类文件中,同时其名称通常会以do_
开头。
为了在菜谱中添加任务,我们可以使用addtask
将一个shell函数或者BitBake风格的Python函数定义为任务。与此同时,由于一个菜谱中可能存在多个任务,因此BitBake提供了after
和before
定义了这些任务的执行顺序,也就是依赖关系,这主要是为了避免并行构建导致的顺序错误,下面有一个定义任务的例子(通过修改前面的printhello.bb
)文件得到的。
DESCRIPTION = "Prints Hello World"
PN = 'printhello'
PV = '1'
python do_printdate() {
import time
bb.plain("Date: " + time.strftime('%Y%m%d', time.gmtime()))
}
addtask printdate
python do_printendmsg() {
bb.plain("Build End")
}
addtask printendmsg
python do_build() {
bb.plain("********************");
bb.plain("* *");
bb.plain("* Hello, World! *");
bb.plain("* *");
bb.plain("********************");
}
addtask build before do_printendmsg after do_printdate
在这个例子中,我们使用addtask
将三个函数添加到了任务列表中,并在最后定义了三个任务的执行顺序,即build
任务需要在printdate
任务前和printendmsg
任务后完成。另外,可以看到我们在添加任务时省略掉了do_
,这是合法的,因为BitBake会自动地为其添加。此时切换到主目录运行bitbake printhello -c printendmsg
(bitbake不指定任务的情况下会默认运行build
任务,-c
可以指定我们要执行的任务)会看到如下内容:
Date: 20230219
********************
* *
* Hello, World! *
* *
********************
Build End
显然,我们运行printendmsg
直接导致了build
和printdate
任务的运行,这是依赖关系造成的。对于after
和before
,它们并不是仅限于定义串行关系,其还可以定义树形关系,也就是说关键字后面可以有一个或多个任务,但要注意不能出现圈形关系。由于每个菜谱中可能会有很多任务,因此它通常会提供do_listtasks
去查看当前菜谱中存在的任务。
BitBake可以添加任务,同样地就可以删除任务。在菜谱中,通过使用deltask
可以删除任务,同时还会删除任务相关的依赖。例如,我们删除上面的build
任务(不是很恰当的例子,build
任务不该删除),其会造成printdate
和printendmsg
任务没有任何关联,也就是说,运行printendmsg
任务不会造成printdate
任务的执行。为了保留依赖关系,我们应该使用下面的方法:
do_build[noexec] = "1"
这样,在运行printendmsg
的时候,仍然会运行printdate
,但不再运行build
任务。另外,在运行任务的时候会发现bitbake报告没有需要执行的任务,这是因为每次bitbake执行完一个任务后会生成stamp文件,下次再运行相同任务时会比对stamp,如果发现任务内容无变化将不再执行该任务。因此,为了再次执行运行过的任务,可以删除xx/tmp/stamps.do_xx
文件或者在命令行中加-f
选项。
如果想要在bitbake构建过程中使用外部环境变量,有一种方法可以实现:
- 先将该环境变量的名称添加到
BB_ENV_PASSTHROUGH_ADDITIONS
,此时该环境变量被允许添加到BitBake的数据仓库中,例如:export BB_ENV_PASSTHROUGH_ADDITIONS="$BB_ENV_PASSTHROUGH_ADDITIONS TEST_ENV"
。 - 然后导出该环境变量,例如:
export TEST_ENV="123"
。
另外值得注意的是,每次修改该环境变量都会导致与该变量相关的任务校验和不一致,因此这些任务每次都会重新构建。
BitBake为了保证每次能够用干净的环境去执行任务,通常会清除掉外部环境导出的或者PassThrough列表(BB_ENV_PASSTHROUGH
和BB_ENV_PASSTHROUGH_ADDITIONS
)中列出的变量,但我们能够通过设置BB_PRESERVE_ENV
来阻止这种清除,例如我们在运行bitbake命令前先在命令行执行如下命令:
export BB_PRESERVE_ENV="1"
这样,在本次bitbake运行时就会使用和上一次一样的环境。因此,如果我们将TEST_ENV
传进了数据仓库,同时设置了BB_PRESERVE_ENV
,那么我们在下次运行bitbake前,即使清除了BB_ENV_PASSTHROUGH_ADDITIONS
中的TEST_ENV
,在环境中也仍然能用TEST_ENV
。但如果我们此时又想要原始的环境变量,那么我们可以通过BB_ORIGENV
(原始数据仓库)得到,例如我们想获得BAR
的原始值:
origenv = d.getVar("BB_ORIGENV", False)
bar = origenv.getVar("BAR", False)
2. 任务配置
除了上一节中提及的依赖关系,任务还有其他的一些属性,这些都可以通过标志(Flag,语法详见前一节)来控制。下面介绍一组BitBake提供的任务属性,其用法与之前的do_build[noexec] = "1"
一样:
[cleandirs]
: 指定任务运行前需要创建的空目录,如果这些目录原本存在将会被删除重建[