目录
写在前面
1. 什么是BitBake
2. BitBake的安装
3. 使用BitBake构建一个HelloWorld工程
后续
《BitBake使用攻略》系列文章将从今天开始不定时的更新,主要讲解BitBake的背景,基本语法,功能及其命令等知识,旨在为即将从事Yocto项目和OpenEmbedded项目的同学做一些预备知识,由于本人能力有限,一些纰漏还望各位指出,话不多说,我们马上进入正题。
BitBake就是比特烧烤,哈哈,皮一下。BitBake是一个开源的构建工具,通过提供必要的元数据,其能构建出从bootloader到应用层各种各样的软件包,可以将其对标GNU Make工具,而BitBake需要的菜谱文件就是GNU Make的CMakeList文件,当然了,也包括各种配置文件,引用官方的解释,BitBake的介绍如下:
Fundamentally, BitBake is a generic task execution engine that allows shell and Python tasks to be run efficiently and in parallel while working within complex inter-task dependency constraints. One of BitBake's main users, OpenEmbedded, takes this core and builds embedded Linux software stacks using a task-oriented approach.
BitBake如此强大,为何我们好像基本没有听说过呢?这是因为BitBake作为Yocto和OpenEmbedded项目的核心构建工具,主要服务于嵌入式工程的构建过程,上手不是特别简单,所以在一般领域不是特别出名,但这不代表他的功能逊色,相反,通过通过编写相应元数据文件和配置文件,你可以构建任何你想要的包。
BitBake有几个比较突出的特点:
BitBake是以任务为单位进行构建的,而这些任务通常是由菜谱文件(后缀为bb)、配置文件(后缀conf)以及类文件(后缀bbclass)所提供。
通过添加一些变量,BitBake可以从本地,甚至是远程服务器获取要用到的源码或补丁等文件。
BitBake采用CS架构,这就提供了一种远程构建的可能。
大致介绍完BitBake后,你可能会觉得这玩意这么厉害是不是特别难学,其实还好,毕竟是一个工具性的软件,只要按着规则来基本没有太大的难度。接下来,我将从一个学习新工具或者新语言必学的项目HelloWorld来为大家介绍BitBake的基本用法。
首先,我们先要下载BitBake软件,大致有三种方式可以供我们获得BitBake:
直接克隆OpenEmbedded维护的BitBake源码包。
从你下载的Yocto或者OpenEmbedded项目代码中取出BitBake源码包。
直接下载官方打包好的BitBake软件包,可以运行下面的命令:
我们使用推荐使用第一种方式,因为我们可以得到一个最稳定的版本,运行下面的命令:
运行完成后,你将获得BitBake的源码目录:
为了可以在任意位置使用bitbake的命令,我们需要将bin目录添加到PATH环境变量中,例如,我可以执行如下命令:
这时,尝试运行一下你的bitbake,看看是否能正确输出版本号:
到此,你的BitBake环境已经准备好啦!
我们最后要到达的效果是使用BitBake工具输出HelloWorld的字样,你可能会觉得这一部分简单,实际上是我想使用官网的一个案例带你去学习BitBake的构建逻辑,同时也提供了一个我们今后学习BitBake使用的工程。
我们先新建一个hello工程,并进入到这个目录下:
这时,我们不禁在想,在这一个空空的目录下怎么去输出HelloWorld呢,你不妨现在试着运行一下构建工具看看会发生什么,运行命令:
可以发现(有点版本可能不会输出),输出信息里提示<code>BBPATH</code>变量未设置,这个变量是干嘛的呢,它是BitBake构建过程中最核心的变量,用于指定bb文件以及conf文件的存储位置,而bb文件中又定义了构建任务,所以在干所有事之前我们要先定义<code>BBPATH</code>变量,将其指定为我们的工程目录,例如:
随后,我们重新使用<code>bitbake</code>命令编译一下工程,这时你会发现系统提示找不到<code>conf/bitbake.conf</code>,而这个文件是bitbake运行时第一个要找到文件,其记录了许多bitbake很重要的全局变量,因此我们创建它:
并在<code>bitbake.conf</code>中添加如下内容:
我们对上面的变量分别做一个简单的介绍:
TMPDIR:用于存放构建生成的文件,类似于输出目录,其中TOPDIR由系统自动赋值为工程目录路径。
CACHE:指定存放缓存文件的地方,通过这些文件,bitbake可以在重新构建时省去很多工作。
STAMP:戳记文件存放目录。
T:存放临时文件,如log文件。
B:bitbake在这个目录下进行构建工作。
再次运行<code>bitbake</code>命令你会发现这次又提示缺少<code>classes/base.bbclass</code>文件,这个文件是一个类文件。在BitBake中,类文件会提供菜谱共有的内容,而<code>base.bbclass</code>是所有菜谱文件(bb文件)的公共基类,是必须提供的,因此我们创建这个文件:
同时,添加如下内容到这个文件中:
这句代码表示继承该类的菜谱必须执行<code>do_build</code>任务,这时候你再运行一下就会发现bitbake没有报错,而是提示没有事情可做,也就是没有提供任务。因此,接下来我们提供一个菜谱文件去指定一些可供bitbake执行的任务。另外为了维护目录的整洁性,我们使用bitbake中层的概念(每个层之间菜谱是独立的,大的工程中都有好多层,用于分离不同种类的文件)。我们新建层<code>meta-mylayer</code>,同时每个层需要又一个配置文件<code>conf/layer.conf</code>:
在这个配置文件中,我们需要为其填充一些配置项,内容如下:
在这个文件中,我们先设置了<code>BBPATH</code>变量,<code>.=</code>表示的是追加,所以我们将<code>LAYERDIR</code>(这个变量会被自动设定为当前层的根路径)内容追加到<code>BBPATH</code>中,表示在这个路径下也可以找到BB文件。而<code>BBFILES</code>是一个正则表达式,使用这个规则可以匹配到我们的菜谱文件。另外,最后的两个变量我们暂时先不说,以后具体讲到菜谱文件再聊,或者你可以参考一下官方的解释:BBFILE_COLLECTIONS , BBFILE_PATTERN。
之后,我们还需要编写我们的第一个菜谱文件,去告诉BitBake我们要做些什么,在<code>meta-mylayer</code>目录下新建一个菜谱文件<code>printhello.bb</code>,内容如下:
在这个文件中,我们定义了三个变量,分别表示描述信息,菜谱名称以及菜谱的版本号。另外我们还定义了一个任务<code>do_build</code>(任务名称以do_开头),内容是使用<code>bb.plain</code>函数打印若干字符串。由于所有BB文件都要继承基类<code>base.bbclass</code>,因此这个BB文件也就必须要执行<code>do_build</code>任务了(参考上面所讲)。
此时,你再次回到根目录下运行<code>bitbake printhello</code>命令(表示我们要构建<code>printhello.bb</code>菜谱),你会发现BitBake似乎并没有找到这个菜谱,这是因为我们还需要一个变量去将新建的层包含到我们的工程中,而这个变量需要定义到<code>conf/bblayers.conf</code>文件中,我们新建<code>conf/bblayers.conf</code>文件,内容如下:
其中,<code>BBLAYERS</code>变量指定了我们要使用的层的绝对路径(你需要把你的层路径替换掉我的)。
现在你检查一下自己的目录是否和我一样:
如果没有文件和内容没有问题,运行<code>bitbake printhello</code>命令,你将获得如下内容:
恭喜你,到此你已经成功的完成了你的BitBake初次旅行,让我们给自己庆祝一下吧!!!
本文案例及介绍参考自Yocto中的文档,有兴趣的同学可以去啃一啃这篇手册。
虽然我们只是输出了一些无用信息,但是我们已经掌握了BitBake最核心的运行逻辑,也对其使用的文件有了一个较为直观的感受。在之后的时间里,我们将继续学习相应的语法知识,命令用法以及怎样使用它完成一个复杂的工程构建任务。当然啦,也希望大家能多多支持一下博主,码字不易,还望一键三连,如果想请博主喝杯茶也可以,右下角可以打赏哦,再次谢谢大家能看到这个地方。
我是chegxy,欢迎关注!!!