aarch64的glibc版本

7
我正在使用x86 Ubuntu Bionic系统交叉编译一个aarch64应用程序,但遇到了glibc版本不匹配的问题。我的交叉编译工具链使用的是v2.27版本,而要运行应用程序的系统则使用v2.24版本。我认为可能是因为我的工具链版本太高,所以决定降级。
在删除所有先前的交叉编译安装后,我安装了gcc-4.8-aarch64-linux-gnu(因为我曾在另一台主机系统上成功地使用此版本交叉编译了应用程序),认为它会安装旧的aarch64版本的glibc到/usr/aarch64-linux-gnu/lib/中。然而,再次安装了v2.27版本(我验证了在安装新的交叉编译工具链之前该目录不存在)。
因此,我的问题有两个:
1.在安装gcc-4.8-aarch64-linux-gnu时,是什么确定了在我的系统上安装哪个aarch64版本的glibc?是否直接与我的系统上x86版本的glibc相关?
2.是否有正确的方式可以在我的系统上安装glibc v2.24(或更低版本)的aarch64版本?

你的问题的答案完全取决于你使用的交叉工具链。有很多种工具链。看起来你安装的那个有一个错误,系统头文件泄漏到了工具链的系统根目录中。否则,glibc版本不匹配根本不会成为问题。 - Florian Weimer
我尝试使用的交叉工具链是通过sudo apt install gcc-aarch64-linux-gcc获得的。然而,当我下载了这个 https://releases.linaro.org/components/toolchain/binaries/latest-4/aarch64-linux-gnu/gcc-linaro-4.9.4-2017.01-x86_64_aarch64-linux-gnu.tar.xz 时,它可以正常工作,因为它包含glibc v2.19。我无法解释为什么通过sudo apt get安装总是安装v2.27... - MulattoKid
所以我进行了一些调查,并得出了一个假设:我发现gcc-aarch64-linux-gnu依赖于libc6-dev-arm64-cross。查看https://packages.ubuntu.com/bionic/libc6-dev-arm64-cross,我发现它默认为```Bionic```的v2.27版本。因此,它基本上是作为依赖项安装的,并且使用最新版本。 - MulattoKid
1个回答

4

我同意你的假设。在连续战斗了40个小时后,我发现了这个确认:

请注意,Ubuntu 21.10(Impish)和Debian 11(Bullseye)有用于gcc 10交叉编译器的软件包。要注意的是,Ubuntu的默认软件包实际上是gcc 11,但Debian 11的默认软件包是gcc 10,这非常令人困惑。Debian和gcc的相似版本号是巧合。现在先忽略Ubuntu软件包是gcc 10.3.0而Debian是gcc 10.2.1的事实。请关注每个软件包的建议和依赖关系。最终,Ubuntu软件包调用libc >= 2.34,而Debian软件包则调用libc >= 2.28。当我从x86上的Impish交叉编译为aarch64上的Bullseye时(尽管已经拥有了目标的完整SYSROOT),在运行时会出现以下错误:/lib/aarch64-linux-gnu/libc.so.6: version 'GLIBC_2.34' not found。但是你的问题仍然存在,主机libc和交叉编译器使用的libc之间是否有任何联系?答案是肯定的可能。
请参阅this中的优秀答案和链接,了解交叉编译器的概述。要点如下:
引用: 您不仅需要交叉编译glibc,还需要交叉编译整个工具链。 工具链组件始终为:ld + gcc + libc + gdb。
因此,C库是交叉编译器的一个重要组成部分。
那么,当您安装gcc-aarch64-linux-gnu时,会发生什么事情?它只是编译器 - 工具链的四个部分之一。
好吧,显然有一些灵活性。从技术上讲,交叉编译器可以是“裸”的。这通常仅在编译操作系统而不是在操作系统上运行的可执行文件时有用。因此,您可以为特殊目的构建特殊的工具链。

但是对于标准用途(在另一种架构上交叉编译Linux),您需要一个典型的工具链。 这就是软件包的依赖项和建议发挥作用的地方。 gcc 总是需要一个 ld,而 ld 总是需要一个 libc,三者之间的关系密不可分。实际上,gcc 是通过使用 ldlibc 中进行复杂的 do-si-do 来构建的。请参考 Preshing on Programming 的 优秀指南 中的此示例:

cross-gcc-steps

可以强制实现分离和链接到其他库, 但这并不容易。

例如,您使用的链接器有一组默认搜索目录。根据 精细手册

默认搜索的路径集合(未使用 -L 指定)取决于 ld 正在使用哪种仿真模式,并且在某些情况下还取决于它的配置方式。

而且它变得更加纠缠。默认情况下,gcc将调用硬编码的动态链接器。对于交叉编译器,它可能是类似于/lib/ld-linux-aarch64.so.1这样的东西。不仅如此,可执行文件也可能以硬编码的路径结尾,作为其程序解释器

同样,如果您小心谨慎,可以拆开工具链和覆盖内容。但是,不仅很难强制执行,特别是如果您有一个复杂的构建,选项和路径的多种组合意味着还经常存在漏洞。因此,您的主机环境可以轻松泄漏到交叉编译工具链中。

总之,交叉编译需要一个工具链。虽然从包管理器中获取跨编译器似乎是一件简单而合法的事情,但它会带来很多隐含的负担。你可以仔细地遵循包依赖关系以检查你正在获取哪个版本,或者使用许多专用的工具链环境,例如crosstool-NG。

非常有趣 - 感谢分享! - MulattoKid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接