如何解决Yocto:创建供其他食谱使用的新交叉编译器
问题
在构建期间创建新的非gcc交叉编译器以供其他配方使用的合适方法是什么?
注意:这是专门关于在编译期间使用的交叉编译器,不是用于由populate_sdk
任务创建的SDK。欢迎提供有关SDK生成的其他信息,但不是问题的重点。
背景
我正在尝试将专有软件框架集成到yocto构建中。出于法律原因(NDA),我无法谈论框架的细节,但是我希望此过程对于生成其他体系结构代码的任何其他专有工具都是相同的。以真正的程序员方式,我们将此框架称为foo
。想像力,我知道。
到目前为止,我已经创建了构建交叉编译器本身的方法(出于简洁和NDA合规性而修剪):
foo-cross.bb
inherit cross
DEPENDS = ""
do_configure () { ... }
do_compile () { ... }
do_install () {
install -d ${D}${libdir}/foo
cp -r ./outdir/* ${D}${libdir}/foo
}
此食谱有效,因为我可以cd
进入构建目录并手动运行二进制文件以完成预期的操作。哇!
接下来,我为依赖于此框架和相关编译器的应用程序创建了一个新的BitBake类(如前所述):
foo.bbclass
DEPENDS += "foo-cross"
# Do not inherit GCC and libc; this is handled by foo-cross
INHIBIT_DEFAULT_DEPS = "1"
do_compile() {
...
}
do_compile[depends] += "foo-cross:do_populate_sysroot"
fakeroot do_install { ... }
do_install[depends] += "virtual/fakeroot-native:do_populate_sysroot"
有了这个,任何配方都应该能够inherit foo
并开始比赛。
问题
主要问题在于,使用此方案会导致recipe-sysroot-native
的内容未填充foo-cross
的安装,显然会导致编译失败。我确实看到testapp/1.0-r0/recipe-sysroot-native/installeddeps/foo-cross
已创建,但在recipe-sysroot-native/${libdir}/foo
中仍然没有。
在一个相关的问题中,我收到一条警告消息,我认为这是我所看到的问题的真正根源:
WARNING: testapp-1.0-r0 do_prepare_recipe_sysroot: Manifest /build/build/tmp/sstate-control/manifest-x86_64_x86_64-nativesdk-foo-cross.populate_sysroot not found in raspberrypi4 armv7vet2hf-neon-vfpv4 armv7vehf-neon-vfpv4 armv7vet2hf-neon armv7vehf-neon armv7vet2hf-vfp armv7vehf-vfp armv7at2hf-vfp armv7ahf-vfp armv6thf-vfp armv6hf-vfp armv5tehf-vfp armv5ehf-vfp armv5thf-vfp armv5hf-vfp allarch x86_64_x86_64-nativesdk (variant '')?
这让我特别困惑,但在一定程度上解释了为什么文件丢失。这引起了许多问题:
- 考虑到我的主机是
x86_64_x86_64-nativesdk
(第一部分)却构建目标是基于ARM的平台,为什么清单被声明为x86_64
? - 鉴于我仅继承
-nativesdk
,cross
部分来自哪里? -
x86_64_x86_64-nativesdk
是在目标列表中,为什么找不到它?
我没有列出我曾尝试解决此错误的所有内容(从事此工作的时间超过了我愿意承认的时间),而是从上而下回到我的问题:设置错误代码的正确方法是什么是否可以与Yocto一起使用新的非gcc交叉编译器?
解决方法
TL; DR
将以下内容添加到foo-cross.bb
:
PN = "foo-cross-${TUNE_PKGARCH}"
PROVIDES = "foo-cross"
等等,
Yocto在准确确定给定配方的行为时会使用许多信息来源。其中包括明显的内容,例如include
或inherit
指令,显式变量设置和配方名称本身的确切格式(${PN}
)。
这是我遇到的最后一个问题。您可以在Yocto文档中找到几个地方,其中提到了特定的配方命名,例如:
以这种方式创建配方时,配方名称必须遵循以下惯例>惯例:
myrecipe-native.bb
不使用此命名约定会导致由依赖该命名约定的现有代码引起的细微问题。
奇怪的是,cross.bbclass
和staging.bbclass
的文档中都没有提到这种智慧的明珠。例如,如果您要查看Poky的gcc-cross.bb
或go-cross.bb
食谱,您可能会怀疑只需添加-cross
并将其命名为一天就足够了。你会错的。要了解原因,请考虑以下staging.bbclass
中的片段(实际文件;不是文档):
native = False
if c.endswith("-native") or "-cross-" in c or "-crosssdk" in c:
native = True
看到了吗?再看一遍。用于匹配跨工具链配方的标识符为-cross-
。请注意尾随连字符。如果像上面一样假设,您将拥有一个交叉编译器配方,该配方继承了cross
,但在登台过程中 not 并未声明为本机配方。嘘。
幸运的是,使用上面的TL; DR可以解决此问题。首先,我们将${PN}
重新定义为foo-cross-${TUNE_ARCH}
。这将导致上述情况和另一种情况(埋在poky/meta/lib/oe/sstatesig.py
中)得以正确解决。其次,我们定义PROVIDES
,以便我们仍然可以依靠foo-cross
而不是完全限定的名称,在我的情况下,该名称非常长。
注释
- 以上分析是在Yocto 3.1上进行的,将来可能会更改。
- 如果给定配方仅可用于某些体系结构,则它仍可以取决于用例而依赖于
foo-cross-longnamehere
。 - 如果您盯着
staging.bbclass
的源头足够长的时间,就会看到帆船。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。