bitbake 使用指南

如果说 Linux 系统镜像是你想吃的一桌饭菜,那么 Yocto 就是一家餐厅,Poky 就是厨房,BitBake 就是厨师。那么,如果我们想定制自己的 Linux,我们应该学会怎么用好 BitBake,或者说把我们的意图告诉 BitBake。总而言之,如果你想定制 Linux 系统的愿望跟你想吃一桌好吃的饭菜一样强烈的话(或者更强烈),你应该好好了解了解 BitBake。


1. 认识 BitBake

OE BitBake 是一个软件组建自动化工具程序,像所有的 build 工具一样(比如 make,ant,jam)控制如何去构建系统并且解决构建依赖。但是又区别于功能单一的工程管理工具(比如make),bitbake不是基于把依赖写死了的makefile,而是收集和管理大量之间没有依赖关系的描述文件(这里我们称为包的配方),然后自动按照正确的顺序进行构建。oe代表OpenEmbedded,而openembedded是一些用来交叉编译,安装和打包的metadata(元数据)。

OpenEmbedded 是一些脚本(shell 和 python 脚本)和数据构成的自动构建系统。脚本实现构建过程,包括下载(fetch)、解包(unpack)、打补丁(patch)、配置(configure)、编译(compile)、安装(install)、打包(package)、staging、做安装包(package_write_ipk)、构建文件系统等。

OE 编译顺序:

do_setscene
do_fetch
do_unpack
do_path
do_configure
do_qa_configure
do_compile
do_stage
do_install
do_package
do_populate_staging
do_package_write_deb
do_package_write
do_distribute_sources
do_qa_staging
do_build
do_rebuild

注意:do_compile 这些函数都是在 OpenEmbedded 的 classes 中定义的,而 bitbake 中并没有对这些进行定义。这说明,bitbake 只是 OE 更底层的一个工具,也就是说,OE 是基于 bitbake 架构来完成的。

数据主要提供两个方面的信息:

  • 特定软件包的构建信息
    怎样获取源代码和补丁?怎样构建,用 Makefile 还是 Autotool?需要向目标编译环境输出哪些文件?需要安装哪些文件?每个软件包都需要描述文件。事实上,每个软件包的不同版本都有一个描述文件。
  • 软件包之间的依赖关系
    构建软件包 A 需要先构建什么主机平台工具,什么目标平台工具?软件包A在编译时依赖哪些软件包?软件包A在运行时依赖哪些软件包?一个目标应包含那些软件包,这些依赖关系把几百个软件包联系在一起,构成了一个完整的系统。

基于bitbake,OE可以满足以下所有要求:

  • 解决交叉编译
  • 解决包之间的依赖关系
  • 必须支持包的管理(tar,rpm,ipk)
  • 必须支持将包作成镜像
  • 必须支持高度的可定制性,以满足不同的机器,主机发行版和架构需求
  • 编写元数据必须是容易的,并且可重用性要好

OE 的主要功能是为各种工程项目的需要编译源码。不管是什么工程,以下任务都是需要做的:

  1. 下载源码包,还有其他的系统支持文件(比如初始化脚本)
  2. 解压源码包,然后打上需要的补丁
  3. 如果需要,对软件包进行配置(比如运行 configure 脚本)
  4. 编译所有的东西
  5. 把编译好的文件打成各种格式的包,然后准备安装

其实这些并没有什么不寻常的,困难的是:

  1. 交叉编译:交叉编译是困难的,大部分软件包根本不支持交叉编译,OE 里包含的都是支持交叉编译的。
  2. 目标系统和主机是不同的:这意味着你不能编译一个程序就直接运行它,因为它要运行在目标板上。很多软件包在编译的时候会编译并且运行一些帮助或者测试程序,这在交叉编译时会导致失败。
  3. 工具链总是很难编译的,交叉工具链更是如此。通常情况下,你可能会选择去下载一个别人做好的,但是使用 OE 你就不需要如此。在 OE 里整个工具链在编译系统的时候都会被创建,OE 的这种方式或许在开始的时候会带来一些困难和不便。但是如果你需要打上补丁或者对工具链做些调整就会很容易。

当然,除此之外,OE 还有很多的功能,其中包括:

  • 同时支持 glibc 和 uclibc
  • 只使用 OE 一个工具你就可以为多种目标机器构建系统
  • 自动编译一切构建时和编译时依赖的包
  • 直接创建各种可以在目标机器上直接运行的镜像(包括 jffs2、ext2.gz、squashfs 等等)
  • 支持各种打包格式
  • 自动构建交叉工具链
  • 支持构建“本地包”(本地包指为了完成编译而给主机编译的包,最终不会用到目标板上)

2. 文件系统里的 OpenEmbedded

OE 环境中最重要的目录有3个:

  1. 放工具的 bitbake 目录
  2. 放元数据的目录
  3. 执行构建的 build 目录

2.1 bitbake 目录

这个目录里的是我们的厨师(或理解为烹饪工具)——bitbake,我们使用它,但通常不需要访问、修改它。

2.2 元数据目录

在 poky 中元数据目录是 meta,Openmoko 中元数据目录是 openembedded。在元数据目录中,有3个目录里是真正的元数据,它们是:classes、conf 和 packages。

2.2.1 packages 目录

所有的配方(recipes)文件(后缀为 .bb)都放在 package 目录,每个相对独立的软件包或构建任务在 package 目录下都有自己的子目录。在一个子目录中可以有多个配方(recipes)文件,它们可能是同一个软件包的不同版本,也可能描述了基于同一个软件包的不同构建目标。

有的配方(recipes)简单,有的配方(recipes)复杂。简单的配方仅描述一个软件包的构建,最复杂的是要求构建文件系统的配方,这个配方文件本身并不长,甚至还很短,但它通过依赖关系将几百个甚至几千个其它配方文件卷入了构建过程。packages 目录的 images 子目录下就是这些要求构建文件系统的配方(recipes)。

2.2.2 classes 目录

这个目录放的是配方(recipes)的类文件(后缀为 .bbclass)。类文件包含了一些 bitbake 任务的定义,例如怎么配置、怎么安装。配方文件继承类文件,也就继承了这些任务的定义。例如:我们如果增加一个使用 autotool 的软件包,只要在配方文件中继承 autotools.bbclass:

inherit autotools

bitbake 就知道怎样使用 autotool 工具配置、编译、安装了。所有的配方文件都自动继承了 base.bbclass。base.bbclass 提供了大部分 bitbake 任务的默认实现。

一个配方文件可以继承多个类文件。以后的文章会介绍 bitbake 的任务,届时会更详细地讨论 bitbake 的继承。目前,我们只要知道继承类文件是一种构建过程的复用方式就可以了。

2.2.3 conf 目录

conf 目录包含编译系统的配置文件(后缀为 .conf)。bitbake 在启动时会执行 bitbake.conf,bitbake.conf 会装载用户提供的 local.conf,然后根据用户在 local.conf 中定义的硬件平台(MACHINE)和发布目标(DISTRO)装载 machine 子目录和 distro 子目录的配置文件。machine 子目录里是与硬件平台相关的配置文件,distro 子目录里是与发布目标相关的配置文件。配置文件负责设置 bitbake 内部使用的环境变量,这些变量会影响整个构建过程。

2.3 build 目录

build 是我们烹饪嵌入式系统的地方(可以想象成餐馆的大厨房),整个构建过程就是在 build 目录的 tmp 子目录完成的。build 目录的 conf 子目录里是用户的配置文件 local.conf。

tmp 目录有7个子目录:cache、cross、rootfs、staging、work、deploy 和 stamps 目录。其中 cache 是 bitbake 内部使用的缓存目录。cross 是构建过程中产生的交叉编译器(所谓交叉编译器就是在主机平台运行,用于编译目标平台代码的编译器)。rootfs 是制作文件系统映像前临时建立的根文件系统。我们的工作中通常不需要访问这3个目录,我们访问比较多的是其它4个目录:staging、work、deploy 和 stamps 目录。

2.3.1 staging 目录

软件包 B 在构建时可能依赖软件包 A 提供的头文件、库文件,也可能要使用软件包 C 生成的工具。staging 目录就是放这些输出文件的地方。

我们必须在配方文件中用“DEPENDS”变量声明构建时的依赖关系。bitbake 就会在构建软件包 B 前先构建软件包 A 和软件包 C,并将软件包 B 需要的头文件、库文件、和工具放在 staging 目录。这样,在构建软件包时,就可以从 staging 目录得到需要的头文件、库文件和工具。

2.3.2 work 目录

所有软件包的解包、打补丁、配置、编译、安装等工作都是在 work 目录进行的。所以 work 目录包含了整个嵌入式系统的完整源代码。

work 目录下按照硬件平台、发行人、目标平台的不同又分了几个目录。所有软件包都被放在对应的子目录中,每个软件包都有一个独立的目录。因为软件包总是根据一个配方文件构建的,所以软件包所在的目录就是对应配方文件的工作目录。在讨论 bitbake 和配方文件时我们还会回来,更仔细地观察配方文件的工作。

2.3.3 deploy 目录

这是保存输出成果的目录。其中 images 目录保存构建成功后产生的文件系统映像、内核映像,ipk 目录保存每个软件包的安装包。我们在修改、构建软件包后,可以在目标平台手工安装 ipk 目录下的对应安装包,确认没有问题后,再制作文件系统映像。

2.3.4 stamps 目录

和 work 目录类似,stamp 目录也按照硬件平台、发行人、目标平台的不同又分了几个子目录。软件包在完成每个 bitbake 任务后都会在对应子目录里 touch 一个对应任务的时间戳,有时我们会手工删除某个软件包的时间戳,强制 bitbake 重新构建这个软件包。

2.3.5 sources 目录

OE 环境的 sources 目录是一个储藏间,用来放从网上下载的源代码包。fetch 任务负责下载代码,放到 sources 目录。


3. BitBake 命令

3.1 查看 bitbake 命令

$ bitbake -h
Usage: bitbake [options] [recipename/target recipe:do_task ...]

    Executes the specified task (default is 'build') for a given set of target recipes (.bb files).
    It is assumed there is a conf/bblayers.conf available in cwd or in BBPATH which
    will provide the layer, BBFILES and other configuration information.

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -b BUILDFILE, --buildfile=BUILDFILE
                        Execute tasks from a specific .bb recipe directly.
                        WARNING: Does not handle any dependencies from other
                        recipes.
  -k, --continue        Continue as much as possible after an error. While the
                        target that failed and anything depending on it cannot
                        be built, as much as possible will be built before
                        stopping.
  -a, --tryaltconfigs   Continue with builds by trying to use alternative
                        providers where possible.
  -f, --force           Force the specified targets/task to run (invalidating
                        any existing stamp file).
  -c CMD, --cmd=CMD     Specify the task to execute. The exact options
                        available depend on the metadata. Some examples might
                        be 'compile' or 'populate_sysroot' or 'listtasks' may
                        give a list of the tasks available.
  -C INVALIDATE_STAMP, --clear-stamp=INVALIDATE_STAMP
                        Invalidate the stamp for the specified task such as
                        'compile' and then run the default task for the
                        specified target(s).
  -r PREFILE, --read=PREFILE
                        Read the specified file before bitbake.conf.
  -R POSTFILE, --postread=POSTFILE
                        Read the specified file after bitbake.conf.
  -v, --verbose         Output more log message data to the terminal.
  -D, --debug           Increase the debug level. You can specify this more
                        than once.
  -n, --dry-run         Don't execute, just go through the motions.
  -S SIGNATURE_HANDLER, --dump-signatures=SIGNATURE_HANDLER
                        Dump out the signature construction information, with
                        no task execution. The SIGNATURE_HANDLER parameter is
                        passed to the handler. Two common values are none and
                        printdiff but the handler may define more/less. none
                        means only dump the signature, printdiff means compare
                        the dumped signature with the cached one.
  -p, --parse-only      Quit after parsing the BB recipes.
  -s, --show-versions   Show current and preferred versions of all recipes.
  -e, --environment     Show the global or per-recipe environment complete
                        with information about where variables were
                        set/changed.
  -g, --graphviz        Save dependency tree information for the specified
                        targets in the dot syntax.
  -I EXTRA_ASSUME_PROVIDED, --ignore-deps=EXTRA_ASSUME_PROVIDED
                        Assume these dependencies don't exist and are already
                        provided (equivalent to ASSUME_PROVIDED). Useful to
                        make dependency graphs more appealing
  -l DEBUG_DOMAINS, --log-domains=DEBUG_DOMAINS
                        Show debug logging for the specified logging domains
  -P, --profile         Profile the command and save reports.
  -u UI, --ui=UI        The user interface to use (depexp, goggle, knotty or
                        ncurses - default knotty).
  -t SERVERTYPE, --servertype=SERVERTYPE
                        Choose which server type to use (process or xmlrpc -
                        default process).
  --token=XMLRPCTOKEN   Specify the connection token to be used when
                        connecting to a remote server.
  --revisions-changed   Set the exit code depending on whether upstream
                        floating revisions have changed or not.
  --server-only         Run bitbake without a UI, only starting a server
                        (cooker) process.
  -B BIND, --bind=BIND  The name/address for the bitbake server to bind to.
  --no-setscene         Do not run any setscene tasks. sstate will be ignored
                        and everything needed, built.
  --setscene-only       Only run setscene tasks, don't run any real tasks.
  --remote-server=REMOTE_SERVER
                        Connect to the specified server.
  -m, --kill-server     Terminate the remote server.
  --observe-only        Connect to a server as an observing-only client.
  --status-only         Check the status of the remote bitbake server.
  -w WRITEEVENTLOG, --write-log=WRITEEVENTLOG
                        Writes the event log of the build to a bitbake event
                        json file. Use '' (empty string) to assign the name
                        automatically.

3.2 bitbake 常用命令

BitBake 参数描述示例备注
<target>直接编译/执行一个 recipebitbake core-image-minimal
-c <task> <target>执行某个 recipe 的某个任务bitbake -c build glibc示例表示执行 glibc 的 do_build 任务

<task>表示要执行的任务:
fetch 表示从 recipe 中定义的地址拉取软件到本地
compile 表示重新编译镜像或软件包
deploy 表示部署镜像或软件包到目标 rootfs 内
cleanall 表示清空整个构建目录
-c listtasks <target>显示某个 recipe 可执行的任务bitbake -c listtasks glibc如果你不确定 target 支持哪些任务,就可以用 listtasks 来查询
-b <xx.bb>用BitBake直接执行这个.bb文件bitbake -b rtl8188eu-driver_0.1.bb单独编译 rtl8188eu-driver 任务
-k有错误发生时也继续构建
-e <target>显示当前的执行环境查找包的原路径:
bitbake -e hello \| grep ^SRC_URI
查找包的安装路径:
bitbake -e hello \| grep ^S=
-s显示所有可以 bitbake 的包bitbake -s \| grep hello例如如果自己在一个Layer下面安装了一个hello.bb,可以查看 hello 这个 package 能否被 bitbake
-v显示执行过程
-vDDDD打印一些调试信息(v 后面可以加多个 D)bitbake -vDDDD -c build glibc
-g <target>显示一个包在 BitBake 时与其他包的依赖关系,生成依赖图bitbake -g glibc在当前目录生成一些文件:
task-depends.dot(任务之间的依赖关系)
package-depends.dot(运行时的目标依赖)
pn-depends.dot(构建时的依赖)
pn-buildlist(包含需要构建的任务列表)

*.dot 文件可以通过 xdot 工具打开

3.3 使用举例

单独编译 kernel、模块、设备树

MYS-6ULX-IOT 开发板对应的 kernel 是 linux-mys6ulx:

$ bitbake -c menuconfig -f -v linux-mys6ulx
$ bitbake -c compile -f -v linux-mys6ulx
$ bitbake -c compile_kernelmodules -f -v linux-mys6ulx
$ bitbake -c deploy -f -v linux-mys6ulx

也有一些资料用 virtual/kernel 来指定 kernel,命令变成这样了:

$ bitbake -c menuconfig virtual/kernel
$ bitbake -c compile -f -v virtual/kernel
$ bitbake -c compile_kernelmodules -f -v virtual/kernel
$ bitbake -c deploy -f -v virtual/kernel

通过 sources/meta-myir-imx6ulx/conf/machine/include/mys6ulx-base.inc 和
sources/meta-myir-imx6ulx/conf/distro/include/myir-imx-preferred-evn.inc 文件,我们可以看出一些端倪:

MACHINE_ARCH_FILTER = "virtual/kernel"

# Handle default kernel
IMX_DEFAULT_KERNEL = "linux-mys6ulx"
IMX_DEFAULT_KERNEL_mx6ul = "linux-mys6ulx"
IMX_DEFAULT_KERNEL_mx6ull = "linux-mys6ulx"
PREFERRED_PROVIDER_virtual/kernel ??= "${IMX_DEFAULT_KERNEL}"

单独编译 u-boot

$ bitbake -c compile -f -v u-boot-mys6ulx
$ bitbake -c deploy -f -v u-boot-mys6ulx

编译文件系统

$ bitbake core-image-minimal
$ bitbake core-image-base
$ bitbake fsl-image-gui
$ bitbake fsl-image-qt5
$ bitbake fsl-image-multimedia

清除编译结果

$ bitbake -c clean -v linux-mys6ulx

清除还包括 clean、cleanall、cleanstate


参考

  • 28
    点赞
  • 132
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
bitbake是OpenEmbedded构建系统的引擎,用于构建嵌入式Linux系统。它通过解析一系列配置文件(主要为recipes,即.bb和.bbappend文件)来创建任务列表,并根据依赖关系依次执行。下面是bitbake的执行流程: 1. 源码获取及处理阶段:bitbake首先会根据配置文件中指定的源码仓库地址,从远程仓库或本地仓库中获取源码。然后,它会根据配置文件中的指令对源码进行处理,例如解压、打补丁等。 2. 配置阶段:在这个阶段,bitbake会根据配置文件中的指令对源码进行配置。它会根据不同的目标平台和编译选项生成相应的配置文件。 3. 编译阶段:在这个阶段,bitbake会根据任务列表逐个执行编译任务。每个任务对应一个recipe文件,其中包含了编译的具体指令和依赖关系。bitbake会根据依赖关系自动解析任务的执行顺序,并执行相应的编译指令。 4. 打包阶段:在编译完成后,bitbake会根据配置文件中的指令对编译结果进行打包。它会将编译生成的二进制文件、库文件、配置文件等打包成一个完整的映像文件或软件包。 5. 清理阶段:在需要清理编译结果时,可以使用bitbake的清理指令。例如,使用"bitbake -c clean -v u-boot"可以清理u-boot的编译结果;使用"bitbake -c cleanall xx-image"可以清理整个映像的编译中间结果;使用"bitbake -c cleansstate xx-image"可以清理映像的编译状态。 总结起来,bitbake的执行流程包括源码获取及处理、配置、编译、打包和清理等阶段,通过解析配置文件和依赖关系来自动化构建嵌入式Linux系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿基米东

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值