yocto添加一个新的机器 machine
1、要添加新计算机,您需要将新机器配置文件添加到图层的 conf/machine
目录。此配置文件提供有关要添加的设备的详细信息。
2、OpenEmbedded构建系统使用机器机配置文件的根名称来引用新机器。
例如,一个给定的机器配置文件 crownbay.conf
,构建系统会将机器识别为“crownbay”。
3、必须在机器配置文件中设置或必须从其他较低级别的配置文件中包含的最重要的几个变量
TARGET_ARCH (e.g. "arm") PREFERRED_PROVIDER_virtual/kernel MACHINE_FEATURES (e.g. "apm screen wifi")
4、这几个变量也可能是需要的
SERIAL_CONSOLES (e.g. "115200;ttyS0 115200;ttyS1") KERNEL_IMAGETYPE (e.g. "zImage") MAGE_FSTYPES (e.g. "tar.gz jffs2")
一个例子:
meta-yocto-bsp/conf/machine/beagblone-yocto.conf
5、如果要创建新的内核菜谱,则通常的菜谱编写规则也适用于设置 SRC_URI
。因此,您需要指定必要的补丁程序,并设置 S
为指向源代码。您需要创建一个do_configure
任务,该任务使用defconfig
文件配置内核 。
您可以通过使用make defconfig
命令来执行此操作,或更常见的做法是,复制合适的 defconfig
文件,然后运行 make oldconfig
。
通过利用inherit kernel
和其他一些linux-*.inc
文件,大多数其他功能都被集中,该类的默认设置通常可以正常运行。
6、如果要扩展现有的内核菜谱,通常只需添加合适的defconfig
文件即可。该文件需要添加到与给定内核配方中其他机器所用defconfig文件类似的位置 。
可能的方法是在SRC_URI中列出文件,并将机器添加到COMPATIBLE_MACHINE中的表达式中 :
COMPATIBLE_MACHINE = '(qemux86|qemumips)'
7、添加一个Formfactor配置文件,主要是硬盘配置信息,需要人工确定的信息
7.1、formfactor配置文件提供有关正在为其生成映像的目标硬件的信息,以及生成系统无法从内核等其他源获取的信息。
7.2、ormfactor配置文件中包含的一些信息示例包括帧缓冲区方向、系统是否具有键盘、键盘相对于屏幕的位置以及屏幕分辨率
7.3、在大多数情况下,构建系统使用合理的默认值。但是,如果需要自定义,则需要在meta/recipes-bsp/formfactor/files
目录中创建一个machconfig文件
7.4、该目录包含特定计算机的目录,例如 qemuarm
和qemux86
。有关可用设置和默认设置的信息,请参见meta/recipes-bsp/formfactor/files/config
同一区域中找到的 文件。
以下是“ qemuarm”计算机的示例:
HAVE_TOUCHSCREEN = 1 HAVE_KEYBOARD = 1 DISPLAY_CAN_ROTATE = 0 DISPLAY_ORIENTATION = 0 #DISPLAY_WIDTH_PIXELS = 640 #DISPLAY_HEIGHT_PIXELS = 480 #DISPLAY_BPP = 16 DISPLAY_DPI = 150 DISPLAY_SUBPIXEL_ORDER = vrgb
8、升级菜谱
有3种方式升级菜谱
1、自动升级帮助器(AUH)设置自动版本升级
2、使用devtool upgrade
来设置半自动版本升级
3、通过手动编辑菜谱来升级配方
8.1、使用自动升级助手(AUH)
AUH实用程序与OpenEmbedded构建系统结合使用,以便根据上游发布的新版本自动生成配方升级。
以下步骤描述了如何设置AUH实用程序
1、如果您没有配置用户和电子邮件,则可以使用以下命令进行配置
$ git config --global user.name some_name $ git config --global user.email username@ domain.com
2、要使用AUH,必须将存储库克隆到开发主机上
AUH不属于OpenEmbedded-Core (OE-Core) 和Poky存储库
$ git clone git://git.yoctoproject.org/auto-upgrade-helper Cloning into 'auto-upgrade-helper'... remote: Counting objects: 768, done. remote: Compressing objects: 100% (300/300), done. remote: Total 768 (delta 499), reused 703 (delta 434) Receiving objects: 100% (768/768), 191.47 KiB | 98.00 KiB/s, done. Resolving deltas: 100% (499/499), done. Checking connectivity... done.
3、创建专用的构建目录
运行 oe-init-build-env
脚本以创建专门用于运行AUH实用程序的新的构建目录
不要使用现有的构建目录及其配置,因为现有的设置可能会导致AUH失败或出现不良行为
$ cd ~/poky $ source oe-init-build-env your_AUH_build_directory
4、在local.conf文件中进行配置,在刚为AUH创建的构建目录中的local.conf文件中需要存在一些设置
a、如果要启用 Build History(可选),则conf/local.conf
文件中需要以下几行 :
INHERIT =+ "buildhistory" BUILDHISTORY_COMMIT = "1"
使用此配置并成功升级后,构建历史记录"diff"文件将出现在构建目录中的upgradehelper/work/recipe/buildhistory-diff.txt文件中.。
b、如果要通过testimage
可选的类启用测试 ,则需要在conf/local.conf
文件中进行以下设置
INHERIT += "testimage"
如果您的发行版默认不启用ptest(而Poky启用),则您在local.conf文件中需要以下内容:
DISTRO_FEATURES_append = " ptest"
5、可选)启动vncserver: 如果您在没有X11会话的服务器中运行,则需要启动vncserver:
$ vncserver :1 $ export DISPLAY=:1
6、创建和编辑AUH配置文件
您需要在构建目录中拥有upgrade-helper/upgrade-helper.conf
配置文件。您可以在 AUH源存储库中找到样本配置文件 。
通读样本文件并根据需要进行配置。例如,如果您在前面所述的 local.conf中启用了构建历史记录,则必须在upgrade-helper.conf中启用它.。
另外,如果您使用的是Poky附带的且位于meta-yocto中的默认maintainers.inc文件, 并且未在upgrade-helper.conf配置中设置
"maintainers_whitelist"或"global_maintainer_override",并且在AUH命令行上指定了"-e all",该实用程序会自动向所有默认维
护者发送电子邮件。请避免这种情况.
8.1.1 如何使用AUH:
1、升级特定菜谱
$ upgrade-helper.py recipe_name
例如:升级xmodmap菜谱 $ upgrade-helper.py xmodmap
2、将特定食谱升级到特定版本
$ upgrade-helper.py recipe_name-tversion 例如,此命令将xmodmap配方升级 到版本1.2.3: $ upgrade-helper.py xmodmap -t 1.2.3
3、将所有食谱升级到最新版本并取消电子邮件通知
$ upgrade-helper.py all
运行AUH实用程序后,您可以在AUH构建目录中找到结果:
${BUILDDIR}/upgrade-helper/timestamp
4、AUH实用程序还会根据层树中成功的升级尝试来创建菜谱更新提交
8.2、使用devtool upgrade
1、要查看devtool upgrade可用的所有命令行选项, 请使用以下帮助命令:
$ devtool upgrade -h
2、如果要查找菜谱当前在上游的版本,而又不升级菜谱的本地版本,则可以使用以下命令:
$ devtool latest-version recipe_name
3、devtool升级工作的自动化程度低于AUH。
具体而言, devtool upgrade仅可在单个命名的菜谱上运行,无法使用镜像执行构建和集成测试,并且不会自动为源树中的更改生成提交.。
4、将本地存储库中2.7.4版本升级到2.9.3
devtool upgrade nano -V 2.9.3
如果不使用 -V 选项,会将菜谱升级到最新版本
5、使用devtool build来构建升级后的菜谱
$ devtool build nano
6、在devtool upgrade
工作流程中,存在部署和测试重建软件的机会。但是,对于此示例,一旦工作空间中的源是干净的,就会运行 devtool finish清理工作空间
一旦tree是干净的,您可以使用以下命令从${BUILDDIR}/workspace/sources/nano目录中清除以下示例中的内容
$ devtool finish nano meta-oe
使用该devtool finish
命令清理工作空间并根据您的提交创建补丁文件。该工具将所有补丁文件放回到nano
在这种情况下命名的子目录的源目录中。
8.3、手动升级菜谱
手动更新多个菜谱的扩展性很差,涉及许多步骤。升级菜谱版本的建议是通过AUH或devtool升级
手动升级的步骤:
1、更改版本:
重命名菜谱,以使版本(即菜谱名称的PV)适当更改。如果版本不是菜谱名称的一部分,请更改菜谱本身中PV设置的值 。
2、更新SRCREV(如果需要):
如果从Git或其他版本控制系统中获取了配方构建的源代码,请进行更新 SRCREV
以指向提交的与新版本相匹配的哈希值。
3、编译软件:
尝试使用BitBake生成菜谱。典型的编译失败情况包含以下几个方面:
3.1、许可声明已针对新版本进行了更新。
对于这种情况,您需要检查对许可证的任何更改,并根据需要更新LICENSE和LIC_FILES_CHKSUM的值.。
3.2、菜谱的旧版本附带的自定义补丁可能无法应用于新版本。
对于这些情况,您需要检查失败。如果升级版本已解决了这些问题,则对于新版本的软件而言,可能不需要补丁程序。
如果需要补丁程序且该打补丁失败,则需要将其重新设置为新版本.。
3.3、尝试构建多个架构(可选):
一旦为给定体系结构成功构建了新软件,就可以通过更改MACHINE变量并重新构建软件来测试其他体系结构的构建.如果要公开发布菜谱,则此可选步骤特别重要.。
3.4、查看上游的变更日志和发行说明:
检查这两项,可以发现是否存在可能破坏向后兼容性的新功能。如果是这样,您需要采取措施缓解或消除这种情况。
3.5、创建可引导映像并测试 (可选):
如果需要,可以通过将新软件引导到实际硬件上来对其进行测试.
3.6、为layer存储库中的更改创建提交:
在所有构建工作完成并且任何测试成功之后,您可以为保存升级菜谱的layer中的任何更改创建提交.。
8.4、查找临时源代码
您可能会发现在开发过程中修改菜谱用来构建软件包的临时源代码很有用。
例如,您正在开发补丁程序,则需要进行一些试验以找出解决方案。最初构建软件包之后,可以迭代地调整Build Directory中的源代码, 然后可以强制重新编译并快速测试更改后的代码。
确定解决方案后,即可以补丁程序的形式保留更改。
在构建过程中,由S变量定义的Build Directory中提供了菜谱用来构建软件包的解压的临时源代码。
下面是源目录中meta/conf/bitbake.conf配置文件中定义的S变量的默认值:
S = "${WORKDIR}/${BP}"
您应该注意,许多菜谱都覆盖了S变量 ,从Git获取其来源的菜谱通常将S设置为${WORKDIR}/git.。
BP表示基本菜谱名称,由名称和版本组成: BP = "${BPN}-${PV}"
菜谱工作目录(WORKDIR)的路径定义如下:
${TMPDIR}/work/${MULTIMACH_TARGET_SYS}/${PN}/${EXTENDPE}${PV}-${PR}
实际目录取决于几个事情:
TMPDIR:顶级构建输出目录。 MULTIMACH_TARGET_SYS:目标系统标识符。 PN:菜谱名称。 EXTENDPE:(如果 PE 未指定,大多数食谱通常如此,EXTENDPE则为空白)。 PV:菜谱版本。 PR:菜谱修订版本。
例如,假设有一个源目录的顶级文件夹名为poky,一个默认的构建目录poky/build,和一个qemux86-poky-linux
目标机器系统。另外假设你的菜谱名称为foo_1.3.0.bb
在这种情况下,构建系统用于构建软件包的工作目录如下:
poky/build/tmp/work/qemux86-poky-linux/foo/1.3.0-r0
8.5、在工作流中使用Quilt
Quilt 是一个功能强大的工具,可让您无需干净的源代码树即可捕获源代码更改。本节概述了可用于修改源代码,测试更改,然后将更改以补丁程序的形式全部使用Quilt保留的典型工作流程。
注意:关于保留对源文件的更改,如果您清除了菜谱或启用了rm_work,则Yocto项目应用程序开发和可扩展软件开发中所述的devtool工作流与使用Quilt的流程相比, Kit(eSDK)手册是更安全的开发流程.
使用Quilt的步骤:
8.5.1、查找源代码
OpenEmbedded构建系统使用的临时源代码保存在 构建目录中
8.5.2、更改工作目录:
您需要位于具有临时源代码的目录中。该目录由S
变量定义 。
8.5.3、创建一个新补丁:
在修改源代码之前,您需要创建一个新补丁。要创建新的补丁文件,请按以下方式使用quilt new :
$ quilt new my_changes.patch
8.5.4、通知quit并添加文件
创建补丁后,您需要将计划编辑的文件通知Quilt.您可以通过将文件添加到刚创建的补丁中来通知Quilt
$ quilt add file1.c file2.c file3.c
8.5.5、编辑文件
在源代码中对添加到补丁中的文件进行更改.。
8.5.6、测试更改
修改源代码后,测试更改的最简单方法是调用do_compile任务, 如以下示例所示:
$ bitbake -c compile -f package
-f 或 --force属性强制执行指定的任务。如果您发现代码有问题,则可以继续进行迭代编辑和重新测试,直到一切正常为止
使用BitBake 运行do_clean
或 do_cleanall
任务(即 bitbake -c clean package 和 bitbake -c cleanall package)后,您对临时源代码所做的所有修改都会消失 。
如果您使用“ 构建期间节省磁盘空间 ”部分中所述的rm_work功能,修改也将消失 。
8.5.7、生成补丁
一旦更改按预期进行,您需要使用Quilt生成包含所有修改的最终补丁.
$ quilt refresh
到这里,这个my_changes.patch补丁文件,具有file1.c, file2.c和file3.c 所有更改,您可以在源(S)目录的patch/子目录中找到生成的补丁文件 。
8.5.8、复制补丁文件
为简单起见,请将补丁文件复制到名为files的目录中,您可以在包含菜谱(.bb)文件或追加(.bbappend)文件的目录中创建该目录。
在此处放置补丁程序可以确保OpenEmbedded构建系统可以找到该补丁程序。接下来,将补丁添加到菜谱的SRC_URI中。
这是一个例子:
SRC_URI += "file://my_changes.patch"
8.6、生成简单映像
8.6.1、构建一个init RAM 文件系统(initramfs)
1、创建initramfs映像菜谱
可以引用在源目录的meta/recipes-core目录中找到的core-image-minimal-initramfs.bb菜谱作为例子。
2、确定是否需要将initramfs映像捆绑到内核映像中
如果您希望将内置的initramfs映像与内核映像捆绑在一起,请在local.conf文件中,将INITRAMFS_IMAGE_BUNDLE变量设置为"1",并设置用于构建内核映像的菜谱中的INITRAMFS_IMAGE变量.。
建议将它与内核镜像进行绑定,以减少依赖
3、设置INITRAMFS_IMAGE_BUNDLE标志会使initramfs映像解压缩到${B}/usr/目录中。然后使用CONFIG_INITRAMFS_SOURCE
变量将解压缩后的initramfs映像传递到内核的Makefile,从而可以将initramfs映像正常地构建到内核中。
4、如果选择不将initramfs映像与内核映像捆绑在一起,则实际上是在使用 Initial RAM Disk(initrd)。
创建initrd主要是通过处理 INITRD_IMAGE
, INITRD_LIVE
和 INITRD_IMAGE_LIVE
变量。有关更多信息,请参见 image-live.bbclass
文件。
5、
(可选)通过initramfs镜像菜谱将项目添加到initramfs镜像
如果通过菜谱将项目添加到initramfs镜像,则应使用 PACKAGE_INSTALL
而不是 IMAGE_INSTALL
。
您可能不希望由image
或 core-image
类来设置默认值,PACKAGE_INSTALL可以更直接地控制添加到图像的内容
6、生成内核映像和initramfs映像
使用BitBake生成内核映像。由于initramfs映像菜谱是内核映像的依赖项,因此,如果您使用了前面介绍的INITRAMFS_IMAGE_BUNDLE
变量,则也将构建initramfs映像并将其与内核映像捆绑在一起 。
8.6.2、构建一个微型系统(Tiny System)
1、为了帮助您查看当前内核和根文件系统大小的位置,可以使用在scripts/tiny/目录中找到的两个工具:
ksize.py: 报告内核构建对象的组件大小. dirsize.py: 报告根文件系统的组件大小.
2、下一个工具和命令可帮助您组织配置片段并以易于理解的形式查看文件依赖性:
merge_config.sh:帮助您管理内核中的配置文件和片段。
使用此工具,您可以将各个配置片段合并在一起。该工具允许您进行覆盖并警告您缺少任何配置选项。该工具非常适合允许您迭代配置,创建最少的配置以及为不同机器创建配置文件,而不必重复您的过程。
该merge_config.sh
脚本是Linux内核Yocto Git代码库中scripts/kconfig
目录的一部分(例如:linux-yocto-3.14
, linux-yocto-3.10
, linux-yocto-3.8
,等等)。
3、bitbake -u taskexp -g
:bitbake_target
将BitBake命令与这些选项一起使用会打开一个依赖关系管理器,您可以从中查看文件依赖关系。了解这些依赖关系后,您可以在裁剪内核和根文件系统的各个部分时做出明智的决定。
8.7、从外部源构建软件 ,使用自己定制的内核或uboot
假设您有一个项目,其中包含带有高度自定义内核的新BSP。而且,暴露给开发团队尽量小的特性,以便他们可以专注于自己的项目并尽可能维护每个人的工作流程.
在这种情况下,您需要在开发机器上进行开发的内核源目录。您希望菜谱的SRC_URI变量指向外部目录并按原样使有用,而不是复制它.。
要使用来自外部源的软件进行构建,您需要做的就是继承externalsrc类,然后将EXTERNALSRC变量设置为指向您的外部源代码。
以下是在local.conf文件中添加的语句
INHERIT += "externalsrc" EXTERNALSRC_pn-myrecipe = "path-to-your-source-tree"
下一个示例显示如何通过EXTERNALSRC
在配方本身或配方的附加文件中进行设置来完成相同的操作:
EXTERNALSRC = "path" EXTERNALSRC_BUILD = "path"
为了使这些设置生效,您必须全局或本地继承externalsrc类
默认情况下,externalsrc.bbclass在与EXTERNALSRC指定的外部源目录不同的目录中构建源代码。
如果需要在与源相同的目录或其他指定目录中构建源,则可以将EXTERNALSRC_BUILD设置为指向该目录:
EXTERNALSRC_BUILD_pn-myrecipe = "path-to-your-source-tree"
8.8、离线构建
为构建中使用的上游源创建一个"snapshot",然后在以后使用该"snapshot"脱机复制构建,这是非常有用的
您需要先准备并填充文件"快照"的下载目录
下载目录准备就绪后,您可以随时在任何计算机上使用它来复制您的构建。
请按照以下步骤来填充您的下载目录。
1、创建一个干净的下载目录
DL_DIR设置为指向空位置或尚不存在的位置
2、从git源生成tarball
DL_DIR = "/home/your-download-dir/" BB_GENERATE_MIRROR_TARBALLS = "1"
3、填充下载目录,不执行构建
$ bitbake target --runonly=fetch
一旦下载目录包含了与源文件有关的所有内容,就可以创建“自己的镜像”并建立目标
请按照以下步骤使用下载目录中的文件来构建目标:
1、仅使用本地文件
在local.conf
文件内部,添加 SOURCE_MIRROR_URL
变量,继承own-mirrors
类,然后将 BB_NO_NETWORK
变量用于local.conf
。
SOURCE_MIRROR_URL ?= "file:///home/your-download-dir/" INHERIT += "own-mirrors" BB_NO_NETWORK = "1"
SOURCE_MIRROR_URL
和 own-mirror
类设置系统使用的下载目录为“own mirror”。使用BB_NO_NETWORK
变量可确保BitBake在步骤3中的提取过程保持本地状态,这意味着将使用“own mirror”中的文件。
2、从干净的环境构建
可以删除${
TMPDIR
}目录或者使用一个新的Build目录
3、构建目标
$ bitbake target
使用已知的镜像源文件的本地"snapshot"来完成构建。源文件"snapshot"的最终压缩包位于downloads目录中
注意:如果菜谱通过将SRCREV设置为${AUTOREV}来尝试查找软件的最新版本,则离线构建将不起作用
SRCREV = "${AUTOREV}"
当菜谱将SRCREV设置为${AUTOREV}时,构建系统将访问网络以尝试确定SCM中软件的最新版本。通常使用AUTOREV的菜谱是自定义或修改的recipes.驻留在公共存储库中的菜谱通常不使用AUTOREV.
4、如果你确实有菜谱使用AUTOREV,那么你可以采取如下步骤来以离线方式来构建该菜谱
1、使能历史记录
2、使用buildhistory-collect-srcrevs命令从构建历史记录中收集存储的SRCREV值
3、一旦有了正确的源修订版,就可以修改这些菜谱以将SRCREV设置为软件的特定版本.
8.9、提高构建速度
BB_NUMBER_THREADS: BitBake同时执行的最大线程数. BB_NUMBER_PARSE_THREADS: BitBake在解析过程中使用的线程数. PARALLEL_MAKE: 在do_compile任务期间将附加选项传递给make命令, 以便在本地构建主机上指定并行编译. PARALLEL_MAKEINST: 在do_compile任务期间将附加选项传递给make命令, 以便在本地构建主机上指定并行安装.
9.0、使用库
1、包含静态库文件
meta/conf/bitbake.conf配置文件中的PACKAGES和FILES_*变量定义如何打包do_install任务安装的文件。
默认情况下, PACKAGES变量包含${PN}-staticdev,它代表所有静态库文件.。
下面是meta/conf/bitbake.conf文件内容,里面可以看见PACKAGES的配置包含了${PN}-staticdev
PACKAGE_BEFORE_PN ?= ""
PACKAGES = "${PN}-dbg ${PN}-staticdev ${PN}-dev ${PN}-doc ${PN}-locale ${PACKAGE_BEFORE_PN} ${PN}"
PACKAGES_DYNAMIC = "^${PN}-locale-.*"
FILES = ""
FILES_${PN} = "${bindir}/* ${sbindir}/* ${libexecdir}/* ${libdir}/lib*${SOLIBS} \
${sysconfdir} ${sharedstatedir} ${localstatedir} \
${base_bindir}/* ${base_sbindir}/* \
${base_libdir}/*${SOLIBS} \
${base_prefix}/lib/udev/rules.d ${prefix}/lib/udev/rules.d \
${datadir}/${BPN} ${libdir}/${BPN}/* \
${datadir}/pixmaps ${datadir}/applications \
${datadir}/idl ${datadir}/omf ${datadir}/sounds \
${libdir}/bonobo/servers"
FILES_${PN}-bin = "${bindir}/* ${sbindir}/*"
FILES_${PN}-doc = "${docdir} ${mandir} ${infodir} ${datadir}/gtk-doc \
${datadir}/gnome/help"
SECTION_${PN}-doc = "doc"
FILES_SOLIBSDEV ?= "${base_libdir}/lib*${SOLIBSDEV} ${libdir}/lib*${SOLIBSDEV}"
FILES_${PN}-dev = "${includedir} ${FILES_SOLIBSDEV} ${libdir}/*.la \
${libdir}/*.o ${libdir}/pkgconfig ${datadir}/pkgconfig \
${datadir}/aclocal ${base_libdir}/*.o \
${libdir}/${BPN}/*.la ${base_libdir}/*.la"
SECTION_${PN}-dev = "devel"
ALLOW_EMPTY_${PN}-dev = "1"
RDEPENDS_${PN}-dev = "${PN} (= ${EXTENDPKGV})"
FILES_${PN}-staticdev = "${libdir}/*.a ${base_libdir}/*.a ${libdir}/${BPN}/*.a"
SECTION_${PN}-staticdev = "devel"
RDEPENDS_${PN}-staticdev = "${PN}-dev (= ${EXTENDPKGV})"
9.1、将多个版本的库文件合并到一个映像中
构建系统提供能够使用不同的目标优化选项或体系架构构建库,并将它们组合在一起成为一个系统映像。您可以根据特定用例的需要,将映像中的不同二进制文件链接到不同的库.此功能称为"Multilib".
虽然Multilib功能最常用于32位和64位差异,但是构建系统使用的方法有助于实现不同的目标优化选项。
您可以编译一些二进制文件以使用一组库,而另一些二进制文件以使用另一组库。这些库在体系结构,编译器选项或其他优化方面可能有所不同。
源目录中的meta-skeleton层中有几个示例:
conf/multilib-example.conf 配置文件 conf/multilib-example2.conf 配置文件 recipes-multilib/images/core-image-multilib-example.bb 菜谱
9.2、准备使用Multilib
为了启用Multilib,首先需要确保您的菜谱已扩展为支持多个库。许多标准配方已经扩展,并且支持多个库。您可以查看meta/conf/multilib.conf
配置文件, 以查看如何使用BBCLASSEXTEND
变量完成此操作 。
最终,所有菜谱都将涵盖在内,并且不需要此列表。
在大多数情况下,Multilib类扩展会自动将包名称从${PN}扩展到 ${MLPREFIX}${PN}
,其中MLPREFIX
是特定的multilib标准变量(例如“ lib32-”或“ lib64-”)。
例如 DEPENDS
, RDEPENDS
, RPROVIDES
, RRECOMMENDS
, PACKAGES
,和 PACKAGES_DYNAMIC
被由系统自动扩展。
如果要手动扩展菜谱中的任何代码,则可以使用 ${MLPREFIX}
变量以确保正确扩展这些名称。此自动扩展代码位于中multilib.bbclass
。
9.3、使用Multilib
MACHINE = "qemux86-64" require conf/multilib.conf MULTILIBS = "multilib:lib32" DEFAULTTUNE_virtclass-multilib-lib32 = "x86" IMAGE_INSTALL_append = " lib32-glib-2.0"
此示例在常规目标软件包旁边启用了一个名为lib32的附加库。当组合这些"lib32"替代方案时,该示例使用"x86"进行调整.
有关此特定调优的信息,请参见meta/conf/machine/include/ia32/arch-ia32.inc.
然后,该示例在所有镜像中都包含lib32-glib-2.0,它说明了一种包含多库依赖项的方法.您可以使用常规镜像构建来包含此依赖关系,例如:
$ bitbake core-image-sato
您还可以使用以下命令专门构建Multilib软件包:
$ bitbake lib32-glib-2.0
9.4、使用外部工具链
您可能需要在开发过程中使用外部工具链。在这种情况下,您需要完成的基本步骤如下:
-
了解已安装的工具链所在的位置。对于需要构建外部工具链的情况,您需要采取单独的步骤来构建和安装工具链。
-
确保
bblayers.conf
通过BBLAYERS
变量将包含工具链的图层添加到文件中 。 -
将文件中的
EXTERNAL_TOOLCHAIN
变量设置为local.conf
安装工具链的位置。
Yocto项目使用的外部工具链的一个很好的例子是Mentor Graphics®Sourcery G ++工具链。您可以在http://github.com/MentorEmbedded/meta-sourcery/的README文件里查看有关如何使用特定图层的信息
9.5、使用Wic工具(这一章没有看完,我跳过了,以后需要做镜像时再来看)
您必须构建一些本地工具,这些本地工具可以在构建系统上运行:
$ bitbake parted-native dosfstools-native mtools-native
在IMAGE_FSTYPES
变量包含wic,在WKS_FILE中包含wic kickstart file的名称
获取帮助信息
$ wic -h $ wic --help $ wic help
例如,以下命令返回对write命令的帮助
$ wic help write
Wic还存在另一种帮助.您可以通过list命令获得有关单个镜像的帮助
$ wic list beaglebone-yocto help
9.6、创建自己的发行版
1、为您的新发行版创建一个 Layers
创建发行层,以便可以将您的元数据和代码分开。强烈建议您创建并使用自己的层进行配置和编码。与仅将配置放入local.conf
配置文件相比,使用您自己的层会在构建多个machine时更容易再现相同的构建配置
2、创建发行配置文件
需要在图层的conf/distro目录中创建发行配置文件。您需要使用您的发行名称(例如mydistro.conf)对其进行命名.
您可以将配置文件的一部分拆分为包含文件,然后从分发配置文件中"require"它们。确保将包含文件放置在图层的conf/distro/include目录中.
您的配置文件需要设置以下必需的变量:
DISTRO_NAME DISTRO_VERSION
这些以下变量是可选的,通常您可以从分发配置文件中进行设置:
DISTRO_FEATURES DISTRO_EXTRA_RDEPENDS DISTRO_EXTRA_RRECOMMENDS TCLIBC
3、提供其他变量
定义发行版需要的其他变量。您可以在local.conf文件中包含几乎所有变量。
4、指向您的发行版配置文件
在构建目录中的local.conf文件中, 将DISTRO变量设置为指向您发行版的配置文件。
例如,如果您的发行版的配置文件名为mydistro.conf,则指向它,如下所示:
DISTRO = "mydistro”
5、如有必要,请向该层添加更多内容 ,使用您的层来保存发行所需的其他信息
1、添加菜谱以安装其他菜谱尚未安装的特定于发行版的配置文件。如果现有菜谱包含特定于发行版的配置文件,则应为其添加一个附加文件(.bbappend) 2、添加任何特定于您的发行版的镜像recipes。 3、为有商标的启动画面添加一个psplash append文件。有关附加文件的信息 4、添加任何其他附加文件以进行特定于各个菜谱的自定义更改
9.7、创建自定义模板配置目录
OpenEmbedded构建系统使用环境变量TEMPLATECONF定位目录,从该目录中收集配置信息,最终将这些信息存储在Build Directory conf目录中。
默认情况下, TEMPLATECONF是在poky仓库中的设置如下:
TEMPLATECONF=${TEMPLATECONF:-meta-poky/conf}
这是构建系统用来查找用于从中构建一些关键配置文件的模板的目录。如果您查看此目录,将看到bblayers.conf.sample,local.conf.sample和conf-notes.txt文件
构建系统使用这些文件来形成各自的bblayers.conf文件,local.conf文件, 并在运行安装脚本时显示BitBake目标的列表.
如果新的Build Directory中的配置要覆盖这些默认配置文件,只需要在.templateconf文件中设置TEMPLATECONF变量, 这个变量位于顶级的源码树下面,是隐藏文件
查看模板文件内容:
这个文件指定了模板的路径是在 meta-poky/conf下面,查看该路径的内容
这里面的文件会生成构建系统的配置文件,例如、/build/conf/bblayer.conf和/build/conf/local.conf文件
一个特殊的文件,conf-notes.txt
这个文件是初始化构建环境脚本(oe-init-build-env )时,Bitbake显示的内容:
可以修改这个文件,来增加显示的内容,例如我添加一个picohood字符
9.8、在构建期间节省磁盘空间
为了在构建期间节省磁盘空间,您可以将以下语句添加到项目的local.conf配置文件中
INHERIT += "rm_work"
创建菜谱后,添加此语句将删除用于创建菜谱的工作目录
9.9、使用包
1、从镜像中排除软件包
如果你想排除一些包,那么可以在local.conf中使用这些变量
BAD_RECOMMENDATIONS:使用此变量可以指定您不想安装的“recommended-only”软件包。 NO_RECOMMENDATIONS: 使用此变量可以防止安装所有“recommended-only”软件包。 PACKAGE_EXCLUDE注意: 使用此变量可以阻止安装特定程序包,无论它们是否为“recommended-only”。您需要认识到,当阻止安装已经安装完成的软件包需要依赖的软件包时,构建过程可能会因错误而失败。
2、增加软件包的版本
为了了解二进制软件包的版本控制,您需要考虑以下因素:
二进制软件包:最终构建并安装到映像中的二进制软件包。 二进制程序包版本:二进制程序包版本由两个组件组成-版本和修订。 PV:菜谱版本。 PV表示要打包的软件的版本。不要将PV与二进制软件包版本混淆。 PR:菜谱修订版本 SRCPV:OpenEmbedded构建系统使用此字符串来帮助定义PV 何时需要在其中包含源代码修订版的值 PR Service:一种基于网络的服务,可自动帮助提供的软件包与现有的软件包管理器应用程序兼容,例如RPM,APT和OPKG。
3、每当二进制软件包的内容更改时,二进制软件包的版本就必须更改。更改二进制软件包的版本是通过更改或调整PR
或PV
值来完成的。增加这些值发生两种方法之一:
自动使用程序包修订服务(PR服务)。 手动递增PR或PV变量。
9.9.1、与PR服务一起使用
尝试在元数据中维护修订号容易出错,不准确,并且会给人们提交菜谱带来麻烦。相反, PR服务会自动生成越来越多的数字,尤其是修订字段,该字段会删除人为因素.
该Yocto计划使用变量以优先级递减,以促进修订编号的顺序(即 PE
, PV
和 PR
分别对应时期,版本和修订)
由于OpenEmbedded构建系统使用“ 签名 ”,这对于给定构建是唯一的,因此构建系统知道何时重新生成软件包。
给定任务的所有输入均由签名表示,签名可以在不同时触发重建。因此,构建系统本身不依赖 PR
,PV
以及 PE
数字触发重建。但是,签名可用于生成这些值。
1、如实现的那样,构建系统使用PR服务的值并附加形式".x"的值,因此r0成为r0.1, r0.2等
2、PR Service的最简单形式是,它存在于构建软件包摘要的单个主机开发系统中(构建系统)
您可以通过在构建目录PRSERV_HOST
中的local.conf
文件中 进行设置来启用本地PR服务 :
PRSERV_HOST = "localhost:0"
服务启动后,程序包将自动获得增加的PR
值,BitBake将负责启动和停止服务器。
3、如果您有一个更复杂的设置,其中多个主机开发系统针对一个公共的共享软件包摘要而工作,那么您将运行一个PR Service,并将其连接到每个建筑系统。
对于这种情况,您需要使用以下bitbake-prserv
命令启动PR Service :
bitbake-prserv --host ip --port port --start
4、除了手动启动该服务之外,您还需要更新每个建筑系统的local.conf文件,以便每个系统指向服务器和端口。
还建议您使用构建历史记录,它将历史记录与运行PR Service的服务器一起添加到二进制软件包版本中。要启用构建历史记录,请将以下内容添加到每个构建系统的local.conf
文件中:
# It is recommended to activate "buildhistory" for testing the PR service INHERIT += "buildhistory" BUILDHISTORY_COMMIT = "1"
9.9.2、手动修改PR
9.9.3、自动增加软件包版本号
1、在获取存储库时, BitBake使用SRCREV变量来确定要从其构建的特定源代码版本。
请将SRCREV变量设置为AUTOREV,以使OpenEmbedded构建系统自动使用软件的最新版本:
SRCREV = "${AUTOREV}"
2、此外,您需要在PV中引用SRCPV,以便在源代码的版本更改时自动更新版本。
这是一个示例
PV = "1.0+git${SRCPV}"
3、OpenEmbedded构建系统将替换 SRCPV
为以下内容:
AUTOINC+source_code_revision
4、构建系统用数字替换了AUTOINC.使用的数字取决于PR Service的状态:
1、如果启用了PR Service,则构建系统将数字递增,这与PR
的行为类似 。此行为会导致线性增加软件包版本,这是理想的。
这是一个例子:
hello-world-git_0.0+git0+b6558dd387-r0.0_armv7a-neon.ipk hello-world-git_0.0+git1+dd2f5c3565-r0.0_armv7a-neon.ipk
2、如果未启用PR Service,则生成系统将AUTOINC
占位符替换为零(即“ 0”)。由于包含了源版本,因此这会导致更改软件包版本。但是,软件包版本不会线性增加。
这是一个例子:
hello-world-git_0.0+git0+b6558dd387-r0.0_armv7a-neon.ipk hello-world-git_0.0+git0+dd2f5c3565-r0.0_armv7a-neon.ipk
3、总之,为此, OpenEmbedded构建系统不跟踪二进制软件包版本的历史记录。
在这种情况下, AUTOINC与PR相当。如果未启用PR服务器, 则仅将软件包版本中的AUTOINC替换为"0"。如果启用了PR服务器,则构建系统会跟踪软件包版本,并在软件包修订版更改时增加编号。
10.0、使用可选的软件包
许多软件将功能拆分为可选模块(或插件),并且所构建的插件可能取决于配置选项。为了避免重复确定菜谱中可用模块的逻辑,或者避免必须手动打包每个模块, OpenEmbedded构建系统提供了动态处理模块打包的功能
要处理可选的模块包装,您需要做两件事:
1、确保模块包装已实际完成.
2、确保您的菜谱满足其他菜谱对可选模块的任何依赖关系
10.0.1、确保模块包装已实际完成.
1、为确保实际完成模块包装,请在菜谱的populate_packages Python函数中使用do_split_packages函数。
do_split_packages函数搜索指定路径下的文件或目录模式,并通过将其附加到PACKAGES变量,并为FILES_packagename, RDEPENDS_packagename,DESCRIPTION_packagename等设置适当的值,
为找到的每个文件或目录创建一个程序包。
这是来自lighttpd菜谱的示例:
python populate_packages_prepend () { lighttpd_libdir = d.expand('${libdir}') do_split_packages(d, lighttpd_libdir, '^mod_(.*)\.so$', 'lighttpd-module-%s', 'Lighttpd module for %s', extra_depends='') }
2、上面的示例在对do_split_packages的调用中指定了许多内容
1、你的菜谱通过do_install搜索安装文件中的目录 2、用于匹配该目录中的模块文件的正则表达式。在示例中,请注意括号(),该括号标记了应从中派生模块名称的表达式部分 3、用于包名称的模式 4、每个包的说明 5、extra_depends的空字符串, 它禁用对lighttpd主软件包的默认依赖关系
如果在${libdir}中找到了一个名为mod_alias.so的文件,则将为该文件创建一个名为lighttpd-module-alias的程序包,并将description设置为"Lighttpd module for alias".。
3、有关显示如何使用do_split_packages的更多示例,请参见poky source存储库的meta/recipes-connectivity/connman/目录中的connman.inc文件。您还可以在meta/classes/kernel.bbclass中找到示例
10.0.2、满足依赖性
1、您可以通过使用PACKAGES_DYNAMIC变量来确保满足这些依赖性。
这是继续前面显示的lighttpd菜谱的示例:
PACKAGES_DYNAMIC = "lighttpd-module-.*"
2、正则表达式中指定的名称当然可以是任何东西。
在此示例中,它是lighttpd-module, 并且被指定为前缀,以确保在构建期间满足以该前缀开头的程序包名称上的任何RDEPENDS和RRECOMMENDS。
如果您正在使用上一节中所述的do_split_packages,则您在PACKAGES_DYNAMIC中输入的值应对应于do_split_packages调用中指定的名称模式
11、运行时包管理
下面几种情况,你希望使用运行时包管理
1、您想向部署的设备提供现场更新(例如安全更新). 2、您希望为设备上运行的一个或多个应用程序提供快速的开发周期. 3、您想在设备上临时安装各种应用程序的"调试"软件包,以便通过允许访问符号和源调试来大大改 4、您希望为设备部署更小的软件包选择,但允许进行现场更新以添加更大的选择以进行自定义.
11.1、构建注意事项
1、您需要注意这些注意事项才能为运行时程序包管理提供支持
当BitBake生成软件包时,它需要知道要使用哪种格式.
在您的配置中,您可以使用PACKAGE_CLASSES变量指定格式:
1、打开构建目录中的local.conf文件(例如〜/poky/build/conf/local.conf)
2、选择所需的包格式,如下所示:
PACKAGE_CLASSES ?= “package_packageformat”
其中packageformat可以是"ipk", "rpm", "deb"或"tar",这是受支持的软件包格式
3、构建完成后,您的软件包将位于${TMPDIR}/deploy/packageformat目录中。
例如,如果${TMPDIR}是tmp,而您选择的包类型是RPM,则你的PRM包在tmp/deploy/rpm目录里面
12、在构建过程中有效的获取源文件
OpenEmbedded构建系统使用通过SRC_URI变量定位的源文件,使用BitBake构建内容时,操作的很大一部分是查找并下载所有源tarball
1、设置有效镜像
Yocto Project构建中的一项重要工作就是简单地下载所有源tarball。也许其他人建立了一个相当大的源tarball目录。
如果是这样,您可以通过在配置文件中添加语句来节省时间,以便构建过程在检查Internet之前先检查本地目录中是否存在现有的tarball。
这是在local.conf
文件中进行设置的有效方法 :
SOURCE_MIRROR_URL ?= "file:///home/you/your-download-dir/" INHERIT += "own-mirrors" BB_GENERATE_MIRROR_TARBALLS = "1" # BB_NO_NETWORK = "1"
上面的例子中BB_GENERATE_MIRROR_TARBALLS变量使OpenEmbedded构建系统生成Git存储库的tarball并将其存储在DL_DIR目录中 ,也可以使用PREMIRRORS变量
2、获取源文件并屏蔽构建
您可以使用另一种方法,在不构建的情况下预取所有源文件。这个方法可以解决所有下载问题,并最终将所有源文件收集到DL_DIR所在的
build/downloads
下载目录中 。
使用以下BitBake命令格式来获取所有必需的源,而无需开始构建:
$ bitbake -c target runall="fetch"
13、选择Initialization Manager
1、使用SysVinit,则无需执行任何操作
2、使用systemd
DISTRO_FEATURES_append = " systemd" VIRTUAL-RUNTIME_init_manager = "systemd"
3、您还可以防止SysVinit分发功能自动启用,如下所示:
DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
这样做会删除所有多余的SysVinit脚本,要从镜像中完全删除初始化脚本,请同时设置此变量:
VIRTUAL-RUNTIME_initscripts = ""
4、将systemd用作主映像,将SysVinit用作修复映像
DISTRO_FEATURES_append = " systemd" VIRTUAL-RUNTIME_init_manager = "systemd"
14、选择设备管理器
Yocto项目提供了多种管理设备管理器的方法(/dev
)
1、持久性和预先填充/dev: 对于这种情况,/dev目录是持久性的,并且在构建期间创建了所需的设备节点。 2、使用devtmpfs与设备管理器: 对于这种情况,该/dev目录是由内核提供的作为内存文件系统,并在运行时由内核自动填充。设备节点的其他配置是通过用户管理器(如udev或) 在用户空间中完成的 busybox-mdev。
1、使用持久和预填充/dev
要将静态方法用于设备填充,需要将USE_DEVFS
变量设置 为“ 0”,如下所示:
USE_DEVFS = "0"
在/dev目录中的内容是在设备列表文件中定义的。IMAGE_DEVICE_TABLES变量定义要使用的设备列表,应在计算机或发行版配置文件中进行设置。
或者,您可以在local.conf配置文件中设置此变量,如果未定义IMAGE_DEVICE_TABLES变量, 则使用默认的device_table-minimal.txt:
IMAGE_DEVICE_TABLES = "device_table-mymachine.txt"
2、使用devtmpfs和设备管理器
要用动态方法来进行设备填充,您需要使用USE_DEVFS变量(并确保将USE_DEVFS变量设置为"1")
USE_DEVFS = "1"
使用这个设置,/dev/目录的内容是有内核通过devtmpfs来填充的,在构建Linux内核时,请确保设置了相应的内核配置变量CONFIG_DEVTMPFS
3、要对设备节点进行更多控制,可以使用udev或 busybox-mdev之类的设备管理器。
您可以通过在machine 或distro 配置文件中定义VIRTUAL-RUNTIME_dev_manager变量来选择设备管理器。或者,您可以在local.conf配置文件中设置此变量:
15、使用外部SCM
如果您正在处理从外部源代码管理器(SCM)提取的菜谱,则可以让OpenEmbedded构建系统注意到添加到SCM的新菜谱更改,然后构建依赖于新配方的结果包。
使用最新版本。这仅适用于可以从中获取合理的修订版本号的SCM。当前,您可以使用Apache Subversion(SVN),Git和Bazaar(BZR)存储库进行此操作。
1、要启用此行为, 菜谱的PV需要引用SRCPV.这是一个示例:
PV = "1.2.3+git${SRCPV}"
2、然后,您可以将以下内容添加到您的 local.conf
:
SRCREV_pn-PN = "${AUTOREV}"
3、PN
是将要启用自动源版本更新的菜谱的名称。
4、如果您不想更新本地配置文件,则可以直接在菜谱中添加以下内容以完成功能的启用:
SRCREV = "${AUTOREV}"
5、Yocto项目提供了一个名为poky-bleeding的发行版,其配置文件包含以下行:
require conf/distro/include/poky-floating-revisions.inc
此行拉入列出的包含文件,该文件包含许多格式完全相同的行:
#SRCREV_pn-opkg-native ?= "${AUTOREV}" #SRCREV_pn-opkg-sdk ?= "${AUTOREV}" #SRCREV_pn-opkg ?= "${AUTOREV}" #SRCREV_pn-opkg-utils-native ?= "${AUTOREV}" #SRCREV_pn-opkg-utils ?= "${AUTOREV}" SRCREV_pn-gconf-dbus ?= "${AUTOREV}" SRCREV_pn-matchbox-common ?= "${AUTOREV}" SRCREV_pn-matchbox-config-gtk ?= "${AUTOREV}" SRCREV_pn-matchbox-desktop ?= "${AUTOREV}" SRCREV_pn-matchbox-keyboard ?= "${AUTOREV}" SRCREV_pn-matchbox-panel-2 ?= "${AUTOREV}" SRCREV_pn-matchbox-themes-extra ?= "${AUTOREV}" SRCREV_pn-matchbox-terminal ?= "${AUTOREV}" SRCREV_pn-matchbox-wm ?= "${AUTOREV}" SRCREV_pn-settings-daemon ?= "${AUTOREV}" SRCREV_pn-screenshot ?= "${AUTOREV}"
这些行允许您尝试构建一个发行版,该发行版跟踪众多软件包的最新开发源。
PR
:配方修订
16、创建根文件系统
要创建只读根文件系统,只需在映像中添加"read-only-rootfs"功能.在镜像菜谱中或在"构建目录"中找到的local.conf文件中使用以下任何
语句,都会导致构建系统创建只读的根文件系统:
IMAGE_FEATURES = "read-only-rootfs" or EXTRA_IMAGE_FEATURES += "read-only-rootfs"
1、安装后脚本
确保在主机系统上的构建过程中创建根文件系统时,可以运行已安装到映像中的软件包的所有安装后(pkg_postinst)脚本,这非常重要 ,因为这些脚本无法在目标设备的首次引导期间运行 。启用"read-only-rootfs"功能后,构建系统将在创建根文件系统期间进行检查,以确保所有安装后脚本均成功。如果在创建根文件系统后仍需要运行这些脚本中的任何一个,则构建将立即失败。这些构建时检查可确保构建失败,而不是目标设备在其初始引导操作期间稍后失败。
2、构建系统解压后的安装后脚本都是经过工程设计的, 因此它们可以在根文件系统创建期间运行。但是,如果创建并添加自定义脚本,则需要确保它们可以在此文件系统创建期间运行
以下是一些常见的问题,这些问题会阻止在根文件系统创建期间运行安装后脚本:
1、在绝对路径前不使用$D: 在创建根文件系统时, 构建系统会定义$D。此外,当脚本在目标设备上运行时, $D是空白。这意味着$D有两个用途:确保路径在主机环境和目标环境中均有效,以及检查以确定哪个环境用作采取适当措施的方法。 2、尝试运行特定于或依赖于目标体系结构的进程: 您可以通过使用在主机系统上运行的本地工具来完成这些尝试,以完成相同的任务,或者通过在QEMU下运行这些进程,具有qemu_run_binary函数
3、启用“只读rootfs”功能后,目标在运行时尝试写入根文件系统的任何尝试都会失败。因此,您必须确保你给进程和应用程序配置了具有写访问权限的目录(例如/tmp
或/var/run
) 。
17、启用和禁用构建历史记录
默认情况下禁用构建历史记录。要启用它,请添加以下INHERIT语句,并在构建目录中的conf/local.conf文件末尾将BUILDHISTORY_COMMIT变量可以设置为"1"在构建目录中的conf/local.conf文件末尾::
INHERIT += "buildhistory" BUILDHISTORY_COMMIT = "1"
构建历史记录信息保存在BUILDHISTORY_DIR变量定义的构建目录中的${TOPDIR}/buildhistory中.
每个程序包的历史记录都包含一个文本文件,该文件具有名称/值对以及有关程序包的信息.例如, buildhistory/packages/i586-pokylinux/busybox/busybox/latest包含以下内容:
PV = 1.22.1 PR = r32 RPROVIDES = RDEPENDS = glibc (>= 2.20) update-alternatives-opkg RRECOMMENDS = busybox-syslog busybox-udhcpc update-rc.d PKGSIZE = 540168 FILES =/usr/bin/*/usr/sbin/*/usr/lib/busybox/*/usr/lib/lib*.so.*\ /etc/com/var/bin/*/sbin/*/lib/*.so.*/lib/udev/rules.d \ /usr/lib/udev/rules.d/usr/share/busybox/usr/lib/busybox/* \ /usr/share/pixmaps/usr/share/applications/usr/share/idl \ /usr/share/omf/usr/share/sounds/usr/lib/bonobo/servers FILELIST =/bin/busybox/bin/busybox.nosuid/bin/busybox.suid/bin/sh \ /etc/busybox.links.nosuid/etc/busybox.links.suid