16 常见问题
16 一般问题
16 Poky 与 OpenEmbedded 有何不同?
Poky 指 Yocto Project 提供的参考发行版,以及一套参考测试配置。
Poky 发行版使用 OpenEmbedded Build System 和 BitBake 构建。构建 Poky 参考发行版涉及以下 metadata:
备注
Poky 曾经也是一个仓库,其中组合了 BitBake、 OpenEmbedded-Core (OE-Core)、 meta-yocto 仓库和 Yocto Project 文档。 这些内容通过 combo-layer 工具合并。
此仓库仍托管于 https://git.yoctoproject.org/poky,对于早于 Whinlatter(5.3)
且仍在维护的版本,仍会继续更新。较新的版本改用 bitbake-setup
克隆并设置初始 OpenEmbedded Build System 环境。
有关 bitbake-setup 的用法,请参阅 Yocto Project 快速构建。
也可以按照《Yocto Project 开发任务手册》的
手动设置 Poky 参考发行版 一节手动设置上述仓库。
16 为何认为 Poky / OpenEmbedded-Core 是稳定的?
以下三个方面有助于保证稳定性:
Yocto Project 团队让 OpenEmbedded-Core (OE-Core) 保持精简、专注, 其中包含约一千个配方,而其他 OpenEmbedded 社区层提供数千个配方。 保持精简使测试和维护更容易。
Yocto Project 团队使用一小组固定的参考硬件以及模拟目标, 运行手动测试和自动化测试。
Yocto Project 使用 autobuilder 提供持续构建和集成测试。
16 是否有使用 OpenEmbedded 构建系统开发的产品?
请参阅 Yocto Project Wiki 中的 使用 Yocto Project 的产品。 如果知道其他此类产品,欢迎补充到该页面。
16 为什么 systemd 不是 Poky 发行版的默认初始化系统?
systemd 是面向桌面 Linux 的初始化系统, 有其特定关注点,与可定制的“嵌入式”构建系统或环境并不完全一致。
它要求使用某些布局和配置,这是可以理解的,但这些要求未必符合 OpenEmbedded-Core (OE-Core) 或 Yocto Project 的目标和方向。 它也不支持我们的所有目标,例如 systemd 对 musl 的支持就存在问题。
如果将其设为默认选项,我们就必须遵循它的所有选择,这并不合适。 因此,它作为配置选项提供,设计目标一致的用户可以选择使用。 我们明确认为它不是处理初始化的唯一方式。
自动化测试通过 poky-altcfg DISTRO 覆盖 systemd,
无需将其设为默认:它经过测试、可以工作,用户也可以自行选择使用。
16 构建环境
16 开发系统缺少依赖怎么办?
如果开发系统中的 Git、tar 和 Python 版本不满足要求, 可以通过多种方式在开发主机上获得所需工具,例如自行构建压缩包或下载压缩包。 有关更新构建工具的步骤,请参阅 “所需的 Git、tar、Python、make 和 gcc 版本” 一节。
16 OpenEmbedded 如何获取源码?能否通过防火墙或代理服务器工作?
构建系统获取源码的方式具有很强的可配置性。 只要 HTTP 传输可用,通常就能配置为在相应环境中获取源码。
查找源码时,构建系统首先尝试本地下载目录(DL_DIR)。 如果未找到,OpenEmbedded Build System 依次尝试 PREMIRRORS、上游源(由 SRC_URI 指定)和 MIRRORS。
假设使用“poky”发行版,OpenEmbedded 构建系统默认对基于源码管理系统的源 使用 Yocto Project 源码 PREMIRRORS,对普通压缩包使用上游源。 如果失败,再回退到其他镜像站,其中包括 Yocto Project 源码镜像站。
例如,可以在 configuration file 中添加类似以下配置, 使构建系统在尝试其他来源之前先尝试指定服务器:
PREMIRRORS:prepend = "\
git://.*/.* https://downloads.yoctoproject.org/mirror/sources/ \
ftp://.*/.* https://downloads.yoctoproject.org/mirror/sources/ \
http://.*/.* https://downloads.yoctoproject.org/mirror/sources/ \
https://.*/.* https://downloads.yoctoproject.org/mirror/sources/ \
"
这些修改会使构建系统拦截 Git、FTP、HTTP 和 HTTPS 请求,
并将其定向到 http:// 源码镜像站。
也可以使用 file:// URL 指向本地目录或网络共享。
另一种选择是设置:
BB_NO_NETWORK = "1"
此语句让 BitBake 在需要访问互联网时直接报错,而不是尝试联网。 如果希望确保只使用本地源码构建,这种方式很有用。
还有一种方式:
BB_FETCH_PREMIRRORONLY = "1"
此语句限制构建系统只能从 PREMIRRORS 获取源码, 同样有助于复现构建。
也可以使用以下方式:
BB_GENERATE_MIRROR_TARBALLS = "1"
此语句让构建系统生成镜像压缩包。如果需要创建镜像服务器,这种方式很有用。 否则,它可能只是增加构建耗时。
最后,假设所处环境的防火墙只允许 HTTP。只要 PREMIRRORS 服务器内容保持最新,就可以对 configuration file 作如下修改:
PREMIRRORS:prepend = "\
git://.*/.* https://downloads.yoctoproject.org/mirror/sources/ \
ftp://.*/.* https://downloads.yoctoproject.org/mirror/sources/ \
http://.*/.* https://downloads.yoctoproject.org/mirror/sources/ \
https://.*/.* https://downloads.yoctoproject.org/mirror/sources/ \
"
BB_FETCH_PREMIRRORONLY = "1"
这些修改使构建系统能够通过 HTTP 获取源码, 而所有对 PREMIRRORS 之外位置的网络访问都会失败。
OpenEmbedded 构建系统大多数源码获取操作由 wget 完成,
因此需要在 .wgetrc 文件中指定代理设置。
单用户场景可将该文件放在主目录中,全局配置则可放在
/usr/local/etc/wgetrc。
以下代码展示如何在 .wgetrc 文件中设置各种类型的代理。
默认情况下,这些设置通过注释禁用;使用时取消注释即可:
# You can set the default proxies for Wget to use for http, https, and ftp.
# They will override the value in the environment.
#https_proxy = http://proxy.yoyodyne.com:18023/
#http_proxy = http://proxy.yoyodyne.com:18023/
#ftp_proxy = http://proxy.yoyodyne.com:18023/
# If you do not want to use proxy at all, set this to off.
#use_proxy = on
构建系统也接受通过标准 shell 环境变量设置的 http_proxy、
ftp_proxy、https_proxy 和 all_proxy,
据此将请求重定向到代理服务器。
Yocto Project 还提供 meta/conf/templates/default/site.conf.sample 文件, 其中展示了需要时如何配置 Git 代理服务器。
备注
更多信息请参阅 “在网络代理后工作”Wiki 页面。
16 使用 OpenEmbedded 构建系统
16 如何使用外部工具链?
请参阅《开发任务手册》的 “按需使用外部工具链”一节。
16 为什么出现 chmod 权限问题?
如果看到错误
chmod: XXXXX new permissions are r-xrwxrwx, not r-xr-xr-x,
很可能是在 NTFS 文件系统上运行构建。
应改为在使用 ext4、btrfs 或 xfs 等现代 Linux 文件系统的分区上构建。
16 下载源码时出现很多 404 错误,是否有问题?
没有问题。OpenEmbedded 构建系统会先检查已配置的源码镜像站, 然后才从上游源下载。搜索对象既包括源码归档, 也包括由源码管理系统管理的软件的预检出版本。 这些检查可以减轻源码管理服务器的负载,因此有助于大规模部署; 即使上游源消失,也可能让构建继续进行。
16 为什么构建会随机失败?
如果同一次构建以完全不同、随机的方式失败,最可能的原因是:
运行构建的硬件存在问题。
在虚拟化环境中运行构建,而虚拟化实现可能存在缺陷。
OpenEmbedded 构建系统处理大量数据,产生大量网络、磁盘和 CPU 活动, 对这些环节中哪怕单个比特的错误也很敏感。 真正随机的故障最终一直都被追溯到硬件或虚拟化问题。
16 为什么构建因 iconv.h 问题失败?
尝试构建 native 配方时,可能收到以下错误,
提示未使用 GNU libiconv,但包含的 iconv.h 来自 libiconv:
#error GNU libiconv not in use but included iconv.h is from libiconv
此时应检查 /usr/local/include/ 中是否存在以前安装的该头文件版本。
如果存在,请卸载它,或者临时重命名后再尝试构建。
这只是“系统泄漏”问题的一种表现:OpenEmbedded 构建系统在 native
构建期间找到了并使用了以前安装的文件。
此类问题不一定局限于 iconv.h。
请确保 /usr/local/include 和 /opt 等位置不会造成这种泄漏。
16 为什么其他配方找不到 *-native 配方提供的文件?
native 配方提供的文件可能没有进入 native 系统根目录, 配方也可能安装到了错误的位置,或者在 do_install 任务期间出现了权限错误。
当软件包使用的构建系统不识别 BitBake 提供的环境变量时,
就可能出现这种情况。促成本问答的实例中,Makefile 使用名为 BINDIR
的环境变量,而没有使用更标准的 bindir。
Makefile 硬编码的默认值“/usr/bin”多数时候能工作,
却不适用于配方的 -native 变体。另一个例子是,Makefile 忽略
DESTDIR,或对该环境变量使用了其他名称,这也可能导致权限错误。
请检查软件包的构建系统是否存在此类问题。
16 能否删除构建输出,从头开始?
可以,而且很简单。使用 BitBake 构建镜像时,所有构建输出都位于运行
构建环境设置脚本(即 oe-init-build-env)时创建的目录中。
此 Build Directory 默认名为 build,也可以自行指定其他名称。
Build Directory 中有一个 tmp 目录。
要删除所有构建输出,同时保留以前构建使用的源码或下载文件,
只需删除 tmp 目录。
16 为什么不能像对配方使用 bbappend 那样追加 bbclass 文件?
Yocto Project 有意不实现这种功能。 类代码的设计目的在于共享和复用,并向用户提供一定程度的配置能力。 我们希望鼓励大家分享变更,从而构建更好的类。
经验和证据表明,如果类支持 append,人们会在自己的层中创建定制修改,
而不是分享并讨论遇到的问题或限制。
这会在引入新层时导致类之间出现难以理解的交互。
因此,我们有意保留这种自然的推动力,鼓励分享类代码的改进和修复。
此外还有技术问题,例如类追加应作用于哪些配方,以及如何融入层模型。 我们认为没有必要引入这些复杂性。
16 如何集成第三方漏洞扫描工具?
OpenEmbedded Build System 使用 create-spdx 类,为构建的每个配方生成包含软件物料清单(SBOM)的 SPDX 文件。 该类还为镜像配方创建最终 SPDX 文档,存放在部署目录 (DEPLOY_DIR_IMAGE)中。 有关 OpenEmbedded Build System 生成的 SBOM 的更多信息, 请参阅《Yocto Project 开发任务手册》的 创建软件物料清单 一节。
某些第三方漏洞扫描工具已经与 OpenEmbedded Build System 生成的 SPDX 文档集成。例如,Blackduck 提供 bd_scan_yocto_via_sbom 工具,以 SPDX 文档为输入扫描漏洞。
这些第三方工具负责为与 Yocto Project SBOM 的集成提供支持。
有关漏洞处理的更多信息,另请参阅《Yocto Project 开发任务手册》的 检查漏洞 一节。
16 定制生成的镜像
16 OpenEmbedded 构建系统会输出什么?
同一组配方可以生成多种格式的输出,因此 OpenEmbedded 构建的输出 取决于启动构建的方式。通常,输出是可直接烧写到目标设备的镜像。
16 如何让 Yocto Project 支持我的开发板?
要添加对新开发板的支持,需要为其创建板级支持包(BSP)层。 有关创建 BSP 层的更多信息,请参阅《Yocto Project 开发任务手册》的 “理解和创建层”一节, 以及 Yocto Project 板级支持包(BSP)手册。
通常,只要开发板不是特别特殊,在 Yocto Project 中添加支持就相当直接。
16 如何让 Yocto Project 支持我的软件包?
要添加软件包,需要创建一个 BitBake 配方。 有关如何创建配方的信息,请参阅《Yocto Project 开发任务手册》的 “编写新配方”一节。
16 为了遵守许可证,需要随产品提供哪些内容?
这是一个复杂的问题,需要咨询律师,确定具体情况所要求的内容。 请记住,要符合 GPL,需要提供足够的信息,使其他人能够重新构建, 并生成与你交付的内容相同的最终结果。 这意味着需要共享源码、应用于源码的所有补丁,以及软件包配置和构建方式 的全部配置信息。
更多许可证信息见《Yocto Project 概览与概念手册》的 “许可证”一节, 以及《Yocto Project 开发任务手册》的 “在产品生命周期中维护开源许可证合规” 一节。
16 重新编译一个软件包后,是否必须完整重新烧写?
OpenEmbedded 构建系统可以构建多种格式的软件包,例如用于 OPKG 的 IPK、
Debian 软件包(.deb)或 RPM。
然后可以使用设备上的软件包工具,只升级修改过的软件包,
就像 Ubuntu 或 Fedora 等桌面发行版一样。不过,目标端的软件包管理完全可选。
16 如何防止软件包被标记为机器专用?
如果软件包只有在某一机器上包含机器专用数据,却在所有情况下都被标记为
机器专用,可以在 .bb 文件中设置
SRC_URI_OVERRIDES_PACKAGE_ARCH = "0"。
不过,必须确保在确有需要的情况下,手动将软件包标记为机器专用。
处理 SRC_URI_OVERRIDES_PACKAGE_ARCH 的代码位于
meta/classes-global/base.bbclass 文件中。
16 target 与 target-native 有什么区别?
*-native 目标设计为在用于构建的系统上运行。
它们通常是辅助构建的工具,例如用于应用补丁的 quilt-native。
非 native 版本则是在目标设备上运行的版本。
16 为什么 -native 配方的 ${bindir} 和 ${libdir} 值很奇怪?
可执行文件和库可能需要在不同于最初安装位置的目录中使用。 更复杂的是,有时它们在编译时就假定从最初的安装目标目录运行, 这种情况下移动它们会导致问题。
这是主流 Linux 发行版的软件包维护者和 OpenEmbedded 构建系统都面临的
基本问题,因此已有成熟的解决方案。
Makefile、Autotools 配置脚本和其他构建系统应遵循 bindir、
libdir、sysconfdir 等环境变量;这些变量指示程序实际运行时
可执行文件、库和数据所在的位置。它们还应遵循 DESTDIR 环境变量,
在实际安装文件时,将其加到所有其他路径变量之前。
按约定,程序不会实际从 DESTDIR 中运行。
OpenEmbedded 构建系统通过配方构建目标架构程序时,
该程序用于纳入正在构建的镜像,最终从镜像的根文件系统运行。
因此,构建系统将 bindir 设为“/usr/bin”,
将 libdir 设为“/usr/lib”,以此类推。
与此同时,DESTDIR 是 Build Directory 中的路径。
但配方构建 native 程序(即用于在构建机器上运行的程序)时,
程序绝不会直接安装到构建机器的根文件系统。
因此,构建系统对 DESTDIR、bindir 及相关变量都使用构建目录内的路径。
为便于理解,请比较以下两个路径:第一个相对常见,第二个则不常见。
为便于阅读,路径被人为拆成多行:
/home/maxtothemax/poky-bootchart2/build/tmp/work/i586-poky-linux/zlib/
1.2.8-r0/sysroot-destdir/usr/bin
/home/maxtothemax/poky-bootchart2/build/tmp/work/x86_64-linux/
zlib-native/1.2.8-r0/sysroot-destdir/home/maxtothemax/poky-bootchart2/
build/tmp/sysroots/x86_64-linux/usr/bin
即使看起来不寻常,这两个路径都是正确的:第一个用于目标配方,
第二个用于 native 配方。这些路径来自 DESTDIR 机制,
虽然看起来奇怪,但它们是正确的,并且在实践中十分有效。
16 如何创建具有更多可用空间的镜像?
默认情况下,OpenEmbedded 构建系统创建的镜像大小是已填充根文件系统的 1.3 倍。要影响镜像大小,需要设置以下配置:
镜像大小: OpenEmbedded 构建系统使用 IMAGE_ROOTFS_SIZE 变量定义镜像大小,单位为 Kbytes。计算时会考虑初始根文件系统大小, 以及所请求的镜像大小、要添加的额外可用磁盘空间等调整。
空间余量: 使用 IMAGE_OVERHEAD_FACTOR 变量定义 构建系统应用于初始镜像大小的乘数,默认值为 1.3。
额外可用空间: 使用 IMAGE_ROOTFS_EXTRA_SPACE 变量 向镜像添加额外可用空间。构建系统确定 IMAGE_ROOTFS_SIZE 后,再将这部分空间添加到镜像中。
16 为什么不支持路径名中的空格?
Yocto Project 团队曾尝试支持这种情况,但 OpenEmbedded 构建系统依赖的
许多工具(例如 autoconf)在路径名包含空格时都会出错。
在这种情况改变之前,团队不会支持路径名中的空格。
16 我在配方中添加了二进制文件,为什么镜像里的文件不同?
最明显的变化通常是系统剥离了调试符号。 设置 INHIBIT_PACKAGE_STRIP 以停止剥离调试符号, 和/或设置 INHIBIT_PACKAGE_DEBUG_SPLIT 以停止将调试符号 拆分到独立文件,可以确保二进制文件保持不变。
16 运行系统中的问题
16 如何禁用触摸屏设备上的光标?
需要按照《Yocto Project 板级支持包(BSP)开发者指南》的
“其他 BSP 专用配方文件”一节,
创建设备形态配置文件。将 HAVE_TOUCHSCREEN 变量设为 1,如下所示:
HAVE_TOUCHSCREEN=1
16 如何始终启用已连接的网络接口?
netbase 配方提供的默认 interfaces 文件不会自动启用网络接口。 因此,需要添加 BSP 专用的 netbase,其中包含 interfaces 文件。 有关创建此类辅助配方文件的信息,请参阅《Yocto Project 板级支持包(BSP) 开发者指南》的 “其他 BSP 专用配方文件”一节。
例如,将以下文件添加到层中:
meta-MACHINE/recipes-bsp/netbase/netbase/MACHINE/interfaces
meta-MACHINE/recipes-bsp/netbase/netbase_5.0.bbappend