回顾
在关于Yocto的先前的文章中,我们讨论了各种主题,比如Yocto是什么、如何下载它、构建基本镜像、创建和添加新的层等等。这里是前面文章的相关链接:
Yocto: 第1部分 - yocto系列之yocto是个什么东东
https://mp.csdn.net/mp_blog/creation/editor/136742286
Yocto: 第2部分 - yocto系列之配置ubuntu主机
https://mp.csdn.net/mp_blog/creation/editor/136742286
Yocto: 第3部分 - yocto系列之构建与运行第一个镜像
https://mp.csdn.net/mp_blog/creation/editor/136760112
Yocto: 第4部分 - yocto系列之针对rk3588平台构建一个基本镜像
https://mp.csdn.net/mp_blog/creation/editor/136742286
Yocto: 第5部分 -yocto系列之创建和添加新的layer
https://blog.csdn.net/hanpca/article/details/136781418?spm=1001.2014.3001.5502
在这篇文章中,我们将讨论如何创建第一个recipe,在此之前,我们将讨论一些Yocto recipes的基础知识:如何命名它们,它们是如何被bitbake发现的,如何为一个非常基本的用例自己编写一个recipe,最后以学习如何使用recipe!
recipes-速成课程
在第1部分中,我们看到了Yocto是一个可扩展性极强的构建系统,它被广泛地用于为我们周围的各种machine创建linux发行版。它使用了一个名为bitbake的工具,它基本上是一个调度器兼执行引擎,可以解析传递给它的元数据,并按照元数据指定的方式执行操作。bitbake是整个构建过程的主导。
Bitbake recipe或简单的recipe是元数据的一种形式,它包含bitbake如何获取源代码、配置源代码、修补源代码、构建源代码、安装源代码的信息,以及bitbake应该对为其编写recipe的单个软件组件做的基本上所有事情。
基本上,bitbake recipe类似于现实生活中食物的食谱------配料、过程、展示、服务,等等!
Yocto官方文档详细说明了创建bitbake recipe的过程,如下图所示。重要的是要明白,并不是所有的recipe都是使用下面完全相同的过程创建的。如果不需要,可以跳过一些步骤。例如:一些recipe可能不需要应用任何补丁,或者根本不需要编译!
怎样命名一个bitbake recipe
Bitbake recipe的命名方法非常简单。它看起来像这样:
basename_version.bb
顾名思义,basename是recipe的基本名称。不允许在此名称中使用保留后缀或前缀,如cross、native、lib等。当然,如果基本名称本身使用了这些单词,那应该没问题。例如,如果有一个能激怒用户的神奇recipe,可以将其命名为turnusercross_0.1。其思想是不要将recipe绑定到架构或类型上。
版本可以是一个点分隔的字符串。惯例是用major.minor或者major.minor.patch。例如,以下是可以接受的命名方式:
somerecipe_1.2.bb
anotherrecipe_1.2.1.bb
bitbake的 recipe放在哪里
Bitbake recipe总是位于Yocto层中。为了使配方对bitbake可见,应该将特定的Yocto层添加到当前构建配置中。需要复习一下如何将layer添加到构建中,可以查看本系列回顾中第5部分。
假设已经将包含recipes的layer添加到构建配置中, bitbake如何找到它?
为了回答这个问题,我们看下第5部分我们创建的layer中的文件layer.conf
最相关的配置是BBPATH和BBFILES。在自动生成的layer.conf中:
BBPATH变量(类似于我们系统中的PATH变量),bitbake用其来定位.bbclass和配置文件。
BBFILES变量是用空格分隔的recipe文件列表,bitbake用其来构建软件。最重要的是,可以在layer.conf文件中使用像*这样的通配符来指定通用路径。语法类似于Python中的glob功能。
基于上述信息可以明确的是,只要recipe文件位于一个命名类似于recipes-的文件夹内,bitbake将会利用通配规则找到它。
一个bitbake recipe框架
在开始定制recipe时,可以使用以下内容作为起点。这个框架直接取自Yocto的手册。请根据需要编写需要的recipe。
DESCRIPTION = "This is a short description of the recipe"
HOMEPAGE = "You can specify your home page "
LICENSE = "Type of license. Eg: GPLv2, MIT, etc."
SECTION = "Useful if package management is required - can omit"
DEPENDS = "Specify the recipes on which your recipe depends"
LIC_FILES_CHKSUM = "md5sum or sha256sum of the license"
SRC_URI = "Where to get the source code from"
为hello world 程序编写一个recipe
在第五部分文章里, 我们创建的定制层级类似如下:
我们创建一个名为recipes-test的文件夹,用来放自定义的recipe文件。这与conf/layer.conf中BBFILES设置的要求一致。文件夹结构现在应该如下所示。
我们写一个打印hello world的.c文件
#include <stdio.h>
int main(void) {
printf("Hello, World!\r\n");
return 0;
}
如果一个recipe应用一个本地可用的 source tree,源码位于命名为files的文件夹中,其中files文件夹与*.bb文件处于同一级。为了保证目录的整洁,我们在recipes-test目录下创建一个名为hwlocal的文件夹,并将files文件夹、.bb文件放于其中,现在recipes-test目录结构如下:
使用框架recipes作为基准,编写hwlocal_0.1.bb中的内容:
接下来我们详细介绍下等号左边的关键字的意义:
DESCRIPTION:简单描述这个recipe的目的
HOMEPAGE:通常这给出一个主页,从中可以获取更多有关当前recipe的信息
LICENSE:这是一个非常重要的信息,对于构建成功与否至关重要。它告诉bitbake在recipe中将要使用的与源代码相关联的许可证类型。Poky附带大量行业中支持的许可证类型。可以在poky安装的路径下查看这些许可证的详细信息:poky/meta/files/common-licenses。
LIC_FILES_CHKSUM:这些信息对于构建的成功同样至关重要。它通知bitbake在哪里可以找到许可证文件,以及它的校验和是什么。如果bitbake计算的校验和与这里提到的校验和不匹配,构建将失败------它发生在QA阶段。
我们刚刚看到了一些许可类型。也可以选择将其中一个许可证复制到源代码树中,然后引用它,也可以使用bitbake环境变量COMMON_LICENSE_DIR直接引用poky安装中提供的许可证。
我们在示例recipe中选择了后一种方法。
SRC_URI:这告诉bitbake在哪里可以找到源代码。为了简单起见,我们将bitbake指向一个名为hello-world-local.c的本地可用文件。默认情况下,bitbake将查看这个文件的files文件夹。请注意,我们如何将文件路径引用为file://,以表明它是一个本地资源。
S:这是构建目录中未打包的配方源代码所在的位置。在处理tarball时,通常不需要显式地指定这个,除非tarball解压后的文件夹不是以<recipe name>-<version name>格式命名的。
但是,由于我们处理的是本地源代码树,所以在bitbake操作(如补丁、编译、配置等)发生时,必须告诉bitbake该源代码将驻留在何处。我们将其指定为名为WORKDIR的环境变量,它是bitbake的活动工作目录。这个链接中
12 Variables Glossary --- The Yocto Project ® 4.3.999 documentation
有更多关于WORKDIR和其他Yocto变量的信息。
do_compile()
这个函数告诉bitbake应该执行什么命令来编译源代码树。示例中的命令是一个相对简单的一行C命令,随着源代码树的增长,指令也会变得复杂。
注意编译器名称和标志是如何作为CC和LDFLAGS传递的-这些是bitbake正确填充的环境变量。
do_install()
这个函数告诉bitbake要在哪里安装编译后得到的二进制输出。示例中编译的输出是一个名为hello-world-local的二进制文件。
在这里告诉bitbake将二进制文件安装到bitbake生成的目标machine镜像的/bin文件夹中。名为bindir的环境变量展开为/bin,名为D的环境变量指向目标machine映像的路径。
提示:可以通过bitbake -e指令查看所有bitbake的环境变量。