1. 什么是bitbake,bitbake可以做什么?
BitBake 是一个使用 Python 写的用于 OpenEmbedded 构建系统时使用的工具,BitBake 与 GNU Make 的关系就像 GNU Make 之于 GCC ,运作方式也类似 GNU Make,但又有所区别:它是一个多任务引擎,可以并行执行 shell 和 Python 任务,每个任务单元根据预定义的元数据来管理源码、配置、编译、打包,并最终将每个任务生成的文件集合成为系统镜像,例如要从源码构建一个 Linux 系统,需要搭建一个生产环境,然后依次生成 LK、Kernel、各种库文件、各种可执行文件,然后集合到一个文件系统里。嵌入式系统都是在使用,比如Yocto 、WindRiver Linux 等。
2. 基于bitbake构建一个最小工程
一:下载bitbake
可以从https://github.com/openembedded/bitbake下载bitbake,这里我下载的版本是1.25
二:添加bitbake到环境变量
这里有两种方法,一种是临时的环境变量,终端关闭即无效,另一种是永久性环境变量,写进profile文件
2.1. 添加到临时的环境变量
mcchen@mcchen-virtual-machine:~/bitbake_workplace/bitbake$ ls
AUTHORS classes lib MANIFEST.in toaster-requirements.txt
bin conf LICENSE meta-tutorial TODO
build contrib LICENSE.GPL-2.0-only meta-two
ChangeLog doc LICENSE.MIT README
mcchen@mcchen-virtual-machine:~/bitbake_workplace/bitbake$ export PATH=~/bitbake_workplace/bitbake/bin/:$PATH
mcchen@mcchen-virtual-machine:~/bitbake_workplace/bitbake$ export PYTHONPATH=~/bitbake_workplace/bitbake/lib/:$PYTHONPATH
2.2. 添加到~/.profile文件,永久性生效
PATH="$HOME/bitbake_workplace/bitbake/bin/:$PATH"
PYTHONPATH="$HOME/bitbake_workplace/bitbake/lib/:$PYTHONPATH"
mcchen@mcchen-virtual-machine:~$ source ~/.profile
2.3.检验bitbake路径是否添加成功,使用bitbake --version, 我这里的版本是1.25的
mcchen@mcchen-virtual-machine:~$ bitbake --version
BitBake Build Tool Core version 1.25.0, bitbake version 1.25.0
三:构建最小bitbake工程
3.1. 工程布局
工程通过layer目录和build目录构成,layer目录主要是放元数据及配置文件,build 目录是 bitbake 命令被执行的地方,BitBake 期望能找到其初始配置文件,并将其生成的所有文件放在这个目录。
3.2. 创建build/conf/bblayers.conf,这是BitBake 在其工作目录(即 build 目录)期望找到的第一个文件,下面在bblayers.conf添加并添加配置信息,内容如下,添加当前目录到 BBPATH,TOPDIR 被 BitBake 设置为当前工作目录,BBFILES为bb文件,后面会添加,添加BBLAYERS路径,bitbake会查找所给定的layers
BBPATH := "${TOPDIR}"
BBFILES ?= ""
BBLAYERS = "$HOME/bitbake_workplace/meta-tutorial"
3.3. 根据BBLAYERS变量的路径,需要创建layer目录“meta-tutorial”,这里的目录在实际项目中可以是项目名或者其它,然后需要创建一个conf/layer.conf文件,内容如下, 添加当前目录到BBPATH,同样的这里的BBFILES后面使用时会添加
BBPATH .= ":${LAYERDIR}"
BBFILES += ""
3.4. 接下来需要创建meta-tutorial/classes/base.bbclass和meta-tutorial/conf/bitbake.conf两个文件,这两个文件的作用后面会讲到,这里为了方便我们可以从bitbake里的conf和classes进行复制到meta-tutorial项目,这里的classes/base.bbclass共享所有的task函数,后面使用时会讲到,而conf/bitbake.conf包含bitbake所需要的变量在这个文件定义
3.5. 有了上面的准备工作之后,基本一个工程已经搭建起来了,先执行下bitbake看看,这里需要进入build工作目录执行命令,从执行结果看,似乎没有任何的task需要执行,build目录下生成tmp目录,后面具体用到时会讲tmp的作用,下面就是开始添加bb文件了
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build$ bitbake
Nothing to do. Use 'bitbake world' to build everything, or run 'bitbake --help' for usage information.
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build$ ls
bitbake-cookerdaemon.log conf tmp
四:添加recipe
4.1. 在田间recipe前,可以先试试执行命令bitbake -s看看,-s的作用就是查看有哪些需要bitbake的task,从执行结果看,确实没有task需要执行
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build$ bitbake -s
ERROR: no recipe files to build, check your BBPATH and BBFILES?
NOTE: Not using a cache. Set CACHE = <directory> to enable.
Recipe Name Latest Version Preferred Version
=========== ============== =================
Summary: There were 13 WARNING messages shown.
Summary: There was 1 ERROR message shown, returning a non-zero exit code.
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build$
4.2 从上面错误提示没有指定CACHE的路径,也就是没找到cache目录,cache目录主要是bitbake缓存meta的一个目录,这个会帮助加速执行后面的命令,我们可以在meta-tutorial/conf/bitbake.conf里进行添加,内容如下,这时候再执行bitbake -s,就不会报错了,只是还没添加bb去让bitbake执行task了
CACHE = "${TMPDIR}/cache/default"
ERROR: no recipe files to build, check your BBPATH and BBFILES?
Recipe Name Latest Version Preferred Version
=========== ============== =================
Summary: There were 13 WARNING messages shown.
Summary: There was 1 ERROR message shown, returning a non-zero exit code.
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build$
4.3 添加第一个recipe到meta-tutorial, 首先告诉bitbake怎么找recipes,通过在meta-tutorial/conf/layer.conf指出recipes的路径,这里使用通配符的目的是让bitbake找到所有的bb文件
BBPATH .= ":${LAYERDIR}"
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb"
4.4 创建第一个recipe,如meta-tutorial/recipes-tutorial/first/first_0.1.bb,里面的task主要是执行打印log简单任务,如下
DESCRIPTION = "This is the first recipe"
PR = "r1"
do_build () {
echo "first recipe: only do some sample shell script"
}
~
这里的简单的recipe first_01.bb里面的内容涉及到几个概念
a. 设置 description 可解释该 recipe 的用途
b. PR 是内部修订数据,在每次修订后应被更新
c. task do_build 覆盖 base.bbclass 中的全局 build task
现在添加了bb文件后,再执行bitbake -s应该可以看到有相关的recipe了,如下
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build$ bitbake -s
Parsing recipes: 100% |################################################################| Time: 0:00:00
Parsing of 1 .bb files complete (0 cached, 1 parsed). 1 targets, 0 skipped, 0 masked, 0 errors.
Recipe Name Latest Version Preferred Version
=========== ============== =================
first :0.1-r1
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build$
4.5 开始执行bitbake first编译first模块
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build$ bitbake first
Parsing recipes: 100% |################################################################| Time: 0:00:00
Parsing of 1 .bb files complete (0 cached, 1 parsed). 1 targets, 0 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
Initialising tasks: 100% |#############################################################| Time: 0:00:00
NOTE: No setscene tasks
NOTE: Executing Tasks
NOTE: Tasks Summary: Attempted 1 tasks of which 0 didn't need to be rerun and all succeeded.
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build$
这里讲下前面说的tmp目录,tmp目录就是bitbake在执行recipe task进入的一个目录,里面主要有work目录,stamps目录,work目录存放recipe的一些源码及编译中间文件等,而stamps目录里面的文件主要就是执行每个task时记录时间戳,下面我们进入到tmp/work/first-0.1-r1/temp,可以看到task执行的一些log, 到此,基本就是一个简单的recipe添加以及执行了,下面讲的是怎样添加一个class和functions
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build/tmp/work/first-0.1-r1/temp$ ls
log.do_build log.do_build.33973 log.task_order run.do_build.33956 run.do_build.33990
log.do_build.33956 log.do_build.33990 run.do_build run.do_build.33973
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build/tmp/work/first-0.1-r1/temp$ cat log.task_order
do_build (33956): log.do_build.33956
do_build (33973): log.do_build.33973
do_build (33990): log.do_build.33990
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build/tmp/work/first-0.1-r1/temp$ cat log.do_build
DEBUG: Executing shell function do_build
first recipe: only do some sample shell script
DEBUG: Shell function do_build finished
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build/tmp/work/first-0.1-r1/temp$
五:创建mybuild class
5.1 创建一个不同的 build 函数,并共享。先在 meta-tutorial 创建 mybuild.class,如 meta-tutorial/classes/mybuild.bbclass
mybuild_do_build () {
echo "now add mybuild_do_build to run it"
}
EXPORT_FUNCTIONS do_build
在 mybuild.class 中,我们添加了一个 build task,它也是一个简单的 shell 函数。mybuild_do 前缀的依据是 class 中 task 定义的规范 classname_do_functionname。
EXPORT_FUNCTIONS 使该 build 函数可被这个 class 的使用者使用,如果不添加这行,则它不会覆盖 base class 中的 build 函数。
5.2 使用添加的class,修改前面first_0.1.bb,
DESCRIPTION = "I am the first recipe"
PR = "r1"
inherit mybuild
def pyfunc(o):
print (dir (o))
python do_mypatch () {
bb.note ("runnin mypatch")
pyfunc(d)
}
addtask mypatch before do_build
a. 这里增加inherit mybuild,即继承 mybuild class,让 myclass_do_build 成为默认 build task
b. 纯 python 函数 pyfunc 获取一些参数,并根据该入参运行 python dir 函数
c. bitbake python 函数 my_patch 添加并注册成一个 task,该 task 要在 build 函数前执行
d. mypatch 函数调用 pyfunc 函数,并传入全局 bitbake 变量 d。d (datastore) 由 bitbake 定义,并一直可用
e. mypatch 函数被注册成一个 task,并要求在 build 函数前执行
这里再进入temp看看编译结果
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build/tmp/work/first-0.1-r1/temp$ ls -l
total 12
lrwxrwxrwx 1 mcchen mcchen 18 11 3 00:19 log.do_build -> log.do_build.34511
-rw-rw-r-- 1 mcchen mcchen 116 11 3 00:19 log.do_build.34511
-rw-rw-r-- 1 mcchen mcchen 37 11 3 00:19 log.task_order
lrwxrwxrwx 1 mcchen mcchen 18 11 3 00:19 run.do_build -> run.do_build.34511
-rwxrwxr-x 1 mcchen mcchen 924 11 3 00:19 run.do_build.34511
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build/tmp/work/first-0.1-r1/temp$ cat log.task_order
do_build (34511): log.do_build.34511
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build/tmp/work/first-0.1-r1/temp$ cat log.do_build
DEBUG: Executing shell function do_build
now add mybuild_do_build to run it
DEBUG: Shell function do_build finished
mcchen@mcchen-virtual-machine:~/bitbake_workplace/build/tmp/work/first-0.1-r1/temp$
六: bitbake几个常用命令选项
bitbake -s 查看可以执行的recipe
bitbake -c cmd_task recipe 执行recipe的某个task, 如bitbake -c clean xxx
bitbake -vD 显示bitbake执行过程的debug,这个在查看bitbake执行的过程很有帮助
bitbake -e 查看bitbake的一些环境变量,当然这个一般也可以从bitbake.conf进行查看
后面如果还需要用到其它的命令选项可以使用bitbake --h进行查看使用方法
基于此,我们已经将bitbake从安装到建立一个可以编译的简单工程,后续需要深入时可以学习下yocto项目,这是一个基于bitbake的开源项目,后面有时间的话可以跟大家分享下该项目如何使用,如何应用到我们的实际项目中来,最后感谢您阅读了本文章,如果有错误的地方,欢迎评论指出,谢谢~~