Yocto:创建一个新的交叉编译器供其他食谱使用
Yocto: Creating a New Cross Compiler for use by Other Recipes
问题
创建新的非 gcc 交叉编译器以供其他配方在构建期间使用的合适方法是什么?
注意:这专门针对在构建期间使用的交叉编译器,NOT 用于由 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 class(像以前一样修剪):
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
(第一部分)但我的构建目标是基于 ARM 的平台,为什么清单声明为 x86_64_x86_64-nativesdk
?
- 考虑到我只是继承
cross
,-nativesdk
部分来自哪里?
x86_64_x86_64-nativesdk
在目标列表中,为什么找不到?
我没有列出我试图解决这个错误的所有事情(我为此工作的时间比我愿意承认的要长),我 return 从头开始回答我的问题:什么是设置新的非 gcc 交叉编译器以与 Yocto 一起使用的正确方法?
TL;DR
将以下内容添加到 foo-cross.bb
:
PN = "foo-cross-${TUNE_PKGARCH}"
PROVIDES = "foo-cross"
等等,什么?
Yocto 在确定确切给定配方的行为方式时会使用多种信息来源。这包括显而易见的事情,例如 include
或 inherit
指令、显式变量设置和 配方名称本身的确切格式 (${PN}
).
这是我的问题的最后一个条件。您可以在 Yocto 文档中找到几个地方,其中提到了特定的配方命名,例如:
When creating a recipe this way, the recipe name must follow this naming >convention:
myrecipe-native.bb
Not using this naming convention can lead to subtle problems caused by existing code that depends on that naming convention.
奇怪的是,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
但 而不是 在暂存期间被声明为本机配方。嘘.
幸运的是,这可以通过上面的 TL;DR 解决。首先,我们重新定义 ${PN}
为 foo-cross-${TUNE_ARCH}
。这会导致上述情况和另一个(隐藏在 poky/meta/lib/oe/sstatesig.py
中)正确解析。其次,我们定义 PROVIDES
以便我们仍然可以依赖 foo-cross
而不是完全限定名称,在我的例子中,它很长。
备注
- 以上分析是在 Yocto 3.1 上进行的,可能会在未来的修订版中发生变化。
- 如果给定的配方仅适用于某些架构,它仍然可以依赖于
foo-cross-longnamehere
,以适合 use-case。
- 如果您盯着来源
staging.bbclass
足够久,您会看到一艘帆船。
问题
创建新的非 gcc 交叉编译器以供其他配方在构建期间使用的合适方法是什么?
注意:这专门针对在构建期间使用的交叉编译器,NOT 用于由 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 class(像以前一样修剪):
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
(第一部分)但我的构建目标是基于 ARM 的平台,为什么清单声明为x86_64_x86_64-nativesdk
? - 考虑到我只是继承
cross
,-nativesdk
部分来自哪里? x86_64_x86_64-nativesdk
在目标列表中,为什么找不到?
我没有列出我试图解决这个错误的所有事情(我为此工作的时间比我愿意承认的要长),我 return 从头开始回答我的问题:什么是设置新的非 gcc 交叉编译器以与 Yocto 一起使用的正确方法?
TL;DR
将以下内容添加到 foo-cross.bb
:
PN = "foo-cross-${TUNE_PKGARCH}"
PROVIDES = "foo-cross"
等等,什么?
Yocto 在确定确切给定配方的行为方式时会使用多种信息来源。这包括显而易见的事情,例如 include
或 inherit
指令、显式变量设置和 配方名称本身的确切格式 (${PN}
).
这是我的问题的最后一个条件。您可以在 Yocto 文档中找到几个地方,其中提到了特定的配方命名,例如:
When creating a recipe this way, the recipe name must follow this naming >convention:
myrecipe-native.bb
Not using this naming convention can lead to subtle problems caused by existing code that depends on that naming convention.
奇怪的是,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
但 而不是 在暂存期间被声明为本机配方。嘘.
幸运的是,这可以通过上面的 TL;DR 解决。首先,我们重新定义 ${PN}
为 foo-cross-${TUNE_ARCH}
。这会导致上述情况和另一个(隐藏在 poky/meta/lib/oe/sstatesig.py
中)正确解析。其次,我们定义 PROVIDES
以便我们仍然可以依赖 foo-cross
而不是完全限定名称,在我的例子中,它很长。
备注
- 以上分析是在 Yocto 3.1 上进行的,可能会在未来的修订版中发生变化。
- 如果给定的配方仅适用于某些架构,它仍然可以依赖于
foo-cross-longnamehere
,以适合 use-case。 - 如果您盯着来源
staging.bbclass
足够久,您会看到一艘帆船。