Yocto 的开发一般包括:创建 Layers、添加新的软件包、扩充或自定义系统镜像、移植到新的硬件平台(添加新的 MACHINE)。
创建图层
Yocto 使用 OpenEmbeded 来构建系统,支持以 Metadata 的形式来组织和管理构建系统所用到的软件包、源码、配置信息等。Metadata 在一定程度上可以理解为 Layers,其实就是文件夹(这些文件夹通常以 meta-xxx 的形式命名)。使用 Layers 来管理源数据有利于保持模块化的设计,Layer 中包含了某些特定功能所需的源数据,层与层之间互不干扰,当构建的系统所需的功能发生变化时,只需要修改该功能对应的 Layer 即可,保持了功能的独立性和模块化设计。
创建图层的步骤
1. 查看已有图层:一般会列出已有的公开、开放的Metadata,当需要创建新图层时,可以先查看网站是否有现成的Metadata,如果有,则直接使用,如果没有,则需要自行创建。
2. 创建一个文件夹来存储Layer中的数据,通常命名为meta-xxx。例如:meta-mylayer、meta-GUI_XYZ、meta-mymachine等。
3.创建Layer配置文件。在新建的Layer文件夹(例如:meta-mylayer)中创建conf/layer.conf文件。layer.conf文件基本框架如下:
各变量含义如下:
(1).bbPATH:将新添加的层路径添加到全局变量bbPATH中,BitBake构建系统时会根据此变量寻找对应的层。
(2)bbFILES:将新添加的Layer中的配方文件(即.bb或者.bbappend文件)添加到全局变量bbFILES中,BitBake构建系统时会根据此变量寻找对应的配方文件。
(3).bbFILE_COLLECTIONS:将图层名称附加到bbFILE_COLLECTIONS变量中,即将图层的文件夹名称meta-xxx中的xxx赋值给bbFILE_COLLECTIONS。
(4).bbFILE_PATTERN:bbFILE_PATTERN变量是用于匹配bbFILES所在层的正则表达式,可以根据基本框架进行修改。
(5)bbFILE_PRIORITY:层级优先级,当不同层级定义相同配方时,会按照bbFILE_PRIORITY对应的优先级高者为准,使用对应的配方文件。
(6)LAYERVERSION:定义Layer的版本信息。
4. 添加内容。根据层的类型,有些层会添加 machine 和 distro 配置。因此需要在层下的 conf/machine/ 文件中添加 machine 配置,在层的 conf/distro/ 文件中添加 distribution 配置。
创建图层时的一些原则
考虑到创建的Layer便于维护且不会影响其他Layer,因此创建Layer时需要遵循一些原则:
避免覆盖其他层中的配方。换句话说,尽量不要将其他层中的整个配方复制到新建的层并进行修改。而是使用 .bbappend 文件方法仅覆盖需要修改的部分。
避免重复包含文件。对于需要包含文件的配方,请使用 .bbappend 文件或在应用时使用相对于原始层的相对路径,例如:使用 require
recipes-core/package/file.inc 而不是 require file.inc。
启用图层
新建层之后需要使能,才能参与系统构建过程。系统构建中用到的层定义在build/conf/bblayers.conf中。对于iMX6ULL,Freescale官方提供了imx-setup-release.sh脚本,修改build/conf/bblayers.conf文件。在初始化Yocto构建目录时,会调用imx-setup-release.sh脚本。因此,修改imx-setup-release.sh脚本如下:
新添加的 echo "bbLAYERS += " ${BSPDIR}
/sources/meta-bird-imx6ull "" >> $
BUILD_DIR/conf/bblayers.conf 将新添加的 meta-bird-imx6ull 添加到 build/conf/bblayers.conf 中的 bbLAYERS 变量中。
使用 .bbappend 文件
用于将元数据附加到其他配方的配方称为 BitBake 附加文件。BitBake 附加文件使用 .bbappend 文件类型后缀,而附加元数据的相应配方使用 .bb 文件类型后缀。.bbappend 文件允许创建的层通过附加或覆盖来更改其他层的内容,而无需将其他配方复制到新创建的层。直观地讲,新创建的层中的 .bbappend 文件与需要修改或附加其他内容的 .bb 文件位于不同的层中。
附件文件(.bbappend)必须与对应的配方(.bb)文件名(或文件名加版本号)一致,例如附件文件someapp_2.1.bbappend只对文件someapp_2.1.bb有效,也就是说当文件someapp_2.1.bb升级为someapp_2.2.bb或者其他版本的.bb文件时,对应的附件文件someapp_2.1.bbappend也必须做相应升级,比如someapp_2.2.bbappend。在构建过程中,当BitBake检测到某个.bbappend文件没有对应的.bb文件时,就会报错。
设置图层优先级
每个层都分配有一个优先级。当同一配方出现在不同层中时,将首先使用优先级值较大的层中的配方。优先级值也会影响 .bbappend 文件。例如,bbFILE_PRIORITY_mylayer =“5”。
需要注意的是:版本号较低但优先级较高的配方可能会被优先执行。
图层管理
BitBake提供了Layer管理工具来查看Layer的一些基本信息,使用方法如下:
可以使用以下命令:
添加 COPYING.MIT 和 README 文件
在Layer中建议添加相应的COPYING.MIT文件和README文件。
自定义系统映像文件
在实际的工程应用中,需要根据不同的需求对系统进行定制,本节简单介绍了几种定制系统的方法,首先让您对定制系统的方法有一个整体的了解,后续章节会讲解定制系统的详细步骤。Yocto 提供了几种定制系统的方法,您可以根据实际的应用场景选择不同的方法。
通过 local.conf 添加包
通过直接修改 build/conf 路径下的 local.conf 配置文件来添加软件包是定制系统的最简单的方法之一。同时,由于直接修改 local.conf 文件,因此这种方法一般只适用于向系统映像文件中添加软件包。在使用 local.conf 文件中的变量添加软件包时,需要注意的是,添加的软件包对所有的系统映像文件都有效。例如,在 local.conf 文件中添加以下语句,将会安装生成的系统映像文件中的“strace”软件:
注意:等号和包名“strace”之间的空格是必须的。
同样的,修改local.conf中的IMAGE_INSTALL_append也会影响所有的镜像文件,如果需要让其只对特定的镜像文件生效,可以通过扩展语句来实现,如:
这样,新添加的strace软件只对core-image-minimal系统映像文件有效。
通过IMAGE_FEATURES和EXTRA_IMAGE_FEATURES添加软件包
另外一种添加包的方式是通过 IMAGE_FEATURES 和 EXTRA_IMAGE_FEATURES 变量。虽然这两个变量的用法几乎一样,但在实际使用中,IMAGE_FEATURES 一般用在 recipe 中,而 EXTRA_IMAGE_FEATURES 一般用在 build/conf 路径下的 local.conf 文件中。一般来说,这两个变量最终都是通过修改 IMAGE_INSTALL 变量来实现的,实际使用中并不常用。
通过.bb文件定制系统镜像
自定义系统镜像的常用方法是使用 .bb 文件。您可以创建一个配方来定义需要添加到镜像文件中的软件包。例如,在新建的 .bb 文件中添加以下代码:
还有一种方法就是修改现有的系统镜像文件,比如你想基于 core-image-sato 构建一个系统镜像文件,但是需要添加 strace 包,那么你可以将
/sources/poky/meta/recipes-sato/images/core-image-sato.bb 文件复制一份,命名为新的 .bb 文件,然后在新的 .bb 文件中添加如下代码来添加 strace 包:
推荐使用此方法。
通过软件包组定制系统镜像
对于复杂的应用程序,可以使用软件包组来定制系统映像,例如:
/sources/poky/meta/recipes-core/packagegroups/packagegroup-base.bb 文件。
自定义主机名
一般来说,主机名与系统中配置的主机名(/etc/hostname)一致。例如,如果 MACHINE 等于“qemux86”,则写入 /etc/hostnam 的主机名是“qemux86”。您可以通过修改配方基础文件中的 hostname 变量来自定义主机名。例如,您可以在 .bbappend 文件中使用以下代码:
或者,在您的配置文件中使用以下代码:
就是这样。
创建菜谱
Metadata(Layer)由一些 Recipe 组成。从形式上看,Recipes 是 Metadata 文件夹下的一些文件夹(再次强调,按照惯例,它们被命名为 Recipes-xxx)。Recipes-xxx 文件夹中的 Recipe(.bb 文件)是 Yocto 项目最基本的组件。OpenEmbedded 构建系统所使用的软件包和其他组件都定义在 Recipes 中。
创建基本食谱
创建新食谱有两种简单的方法:
本教程主要讲解第二种方法,通常在recipe中定义一些变量来定义要使用的软件包,基本框架如下:
存储和命名食谱
通常,创建完基本配方后,需要按照一定的目录框架将配方放在合适的位置,以保证 OpenEmbedded 在构建系统时能够找到它们。OpenEmbedded 通过 Layer(meta-xxx 文件夹)下 conf/layer.conf 中的变量 bbFILES 来查找构建过程中用到的配方。其典型应用如下:
因此必须保证新建的配方在层中有正确的路径。另外配方文件的命名也要遵循一定的规则,如下所示:
使用小写字符,并且不要包含保留后缀 -native、-cross、-initial 或 -dev。例如:cups_1.7.0.bb、gawk_4.0.2.bb、irssi_0.8.16-rc1.bb 等。
编写菜谱
对于新创建的配方,往往需要不断修改、编译、迭代,才能逐步实现最终的功能。使用 fls-setup-release.sh 脚本初始化 Yocto 构建目录后,会自动进入构建目录。在此路径下,可以使用以下命令编译配方:
其中basename为配方文件名。在编译过程中,OpenEmbedded编译系统会为每个配方建立一个临时文件夹,用于存放解压后的文件、日志文件等。每个配方的临时文件夹组织如下:
例如假设生成的系统架构是qemux86-poky-linux,配方文件是foo_1.3.0.bb,则会生成以下文件:
在此路径下还可以看到image、packages-spilt、temp等文件夹,编译完成后可以检查这些文件夹的内容,判断编译过程是否正确。
获取源代码
构建系统的过程其实就是将一些软件源代码编译成系统镜像文件的过程。因此,recipe的第一步就是定义如何获取相关的软件源代码。在recipe中,软件源代码的位置由SRC_URI变量定义。BitBake编译系统镜像文件的过程可以分为几个任务,逐步完成。其中一个任务do_fetch会根据SRC_URI变量值的前缀,决定使用哪个fetcher以及从哪里获取软件源代码。获取源代码之后,do_patch任务也会根据SRC_URI变量值进行补丁应用。
配方中的 SRC_URI 定义了软件源代码的唯一地址,建议 SRC_URI 变量中定义的软件源代码地址包含 ${PV},这样在获取软件源代码的过程中可以使用配方文件名中定义的版本。同时,后续需要升级软件版本时,只需要升级配方文件名的版本号即可。例如:在
meta/recipes-devtools/cdrtools/cdrtoolsnative_3.01a20.bb 这个配方中,SRC_URI 变量值使用“PV”值。
你也可以通过SCM(Source Control Managers)获取软件源代码,比如Git。对于Git,你还需要在recipe中定义SRCREV和SRCPV变量值,例如:
meta/recipeskernel/blktrace/blktrace_git.bb:
其中,SRCPV = "${@bb.fetch2.get_srcrev(d)}"
另外,如果 SRC_URI 指向的软件源地址不是来自 SCM,而是远程服务器或其他地址上的软件源包,则需要定义相应的软件源包校验和,以便 BitBake 在编译时通过校验和判断软件包的完整性。例如:
解压源代码
如果源代码是以压缩包的形式获得的,do_unpack任务会在编译过程中对压缩包进行解压。
补丁代码
有时获取软件源代码后,需要打补丁。补丁代码在SRC_URI中,以.patch、.diff或者以这些后缀的压缩包(如:diff.gz)结尾。执行do_patch任务时,会自动打补丁。
执照
在配方中,您需要包含 LICENSE 和 LIC_FILES_CHKSUM 变量。例如:
LICENSE 变量决定了软件所使用的许可证,一般来说,对应软件包的许可证定义可以在软件包的说明中找到,如 COPYING、LICENSE、README 等文件,也可以在软件源代码文件的头部找到相关信息。
配置配方
大多数软件都提供了一些在编译前配置软件的方法。一般来说,使用带有参数选项的脚本或配置文件是一种典型的方法。在 OpenEmbedded 的编译过程中也是如此。其中,软件配置的一大块就是在软件编译过程中检测依赖关系。软件包的依赖关系可以通过配方文件中的 DEPENDS 变量值来指定。这些依赖关系通常在软件包的描述文档中提到。一般来说,软件包的配置项可以分为以下三类:
Autotools:对于提供 configure.ac 文件的软件包,一般会使用 Autotools 工具进行配置,此时直接修改 configure.ac 文件即可,不过需要注意的是,由于使用了 Autotools,所以需要在 Recipe 中引入 autotools 类,而不需要再在 Recipe 中包含 do_configure 任务。
CMake:对于提供CMakeLists.txt文件的软件包,一般会使用CMake工具进行配置,这样的软件包只需要直接修改CMakeLists.txt配置文件即可。同样,由于使用了CMake,因此需要在recipe中引入cmake类,而不需要再recipe中包含do_configure任务。
其他:对于不使用 Autotools 或 CMake 且需要配置的包,需要在 recipe 中提供一个 do_configure 任务,在编译前对包进行配置。当然,如果包不需要任何配置,则例外。
OpenEmbedded编译完成后可以通过log.do_configure文件查看软件包的配置项,判断配置项是否成功。
编写食谱
获取、解压并配置软件源代码后,BitBake会通过do_compile任务自动开始编译配方。
安装应用程序
Linux下安装软件的一般流程如下:
创建安装目录
复制库
复制可执行程序
根据需要有选择地配置和启动服务
在配方编译的do_install任务中,将构建好的文件及其层级结构复制到生成的镜像文件对应位置,实现软件的安装。不同的软件编译方式会有不同的安装方式:
启用系统服务
可以在recipe中添加一些定义,安装一些需要在系统启动时或者后台运行的进程服务。当需要添加系统服务时,可以使用recipe中的do_install_append函数安装相应的服务。当然如果recipe中已经存在do_install函数,在do_install中安装系统服务也是更好的选择。OpenEmbedded提供了两种方式来启动系统服务:
文档配套教学视频B站搜索“嵌入式Sun”