关于使用bitbake构建嵌入式系统的学习总结

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的开源项目,后面有时间的话可以跟大家分享下该项目如何使用,如何应用到我们的实际项目中来,最后感谢您阅读了本文章,如果有错误的地方,欢迎评论指出,谢谢~~

发布了33 篇原创文章 · 获赞 7 · 访问量 8347

猜你喜欢

转载自blog.csdn.net/muchong123/article/details/102672976