【问题标题】:glibc version for aarch64aarch64 的 glibc 版本
【发布时间】:2020-05-09 05:53:32
【问题描述】:

我在我的x86 Ubuntu Bionic 系统上交叉编译aarch64 的应用程序,我遇到了glibc 版本不匹配的问题。我的交叉编译工具链使用的是 v2.27,而运行应用程序的系统使用的是 v2.24。我想可能是因为我的工具链版本太高,所以我决定降级。

在删除所有以前的交叉编译安装后,我安装了gcc-4.8-aarch64-linux-gnu(因为我已经在不同的主机系统上成功地交叉编译了这个版本的应用程序),认为它会安装一个旧的aarch64 版本的@ 987654328@ 至/usr/aarch64-linux-gnu/lib/。但是,再次安装了 v2.27(我在安装新的交叉编译工具链之前验证了该目录不存在)。

所以我的问题是双重的:

  1. 在安装gcc-4.8-aarch64-linux-gnu 时,是什么决定了在我的系统上安装glibc 的哪个aarch64 版本?是否直接与我自己系统的x86 版本的glibc 绑定?
  2. 是否有正确的方法在我的系统上安装aarch64 版本的glibc v2.24(或更低版本)?

【问题讨论】:

  • 问题的答案完全取决于您使用的跨工​​具链。其中有很多。看起来您安装的那个有一个错误,系统标头泄漏到工具链 sysroot 中。否则,glibc 版本不匹配根本不是问题。
  • 我尝试过的跨工具链,我通过sudo apt install gcc-aarch64-linux-gcc获得。但是,当我下载这个releases.linaro.org/components/toolchain/binaries/latest-4/… 时,它起作用了,因为它包含glibc v2.19。我无法解释为什么通过sudo apt get 安装总是安装 v2.27...
  • 所以我环顾四周,提出了一个假设:我看到gcc-aarch64-linux-gnu 依赖于libc6-dev-arm64-cross。查看packages.ubuntu.com/bionic/libc6-dev-arm64-cross,我发现Bionic 默认为v2.27。所以本质上,它是作为依赖安装的,并且使用的是最新版本。

标签: linux ubuntu glibc libc


【解决方案1】:

我同意你的假设。在连续 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。

果然,当我从 Impish on x86 for Bullseye on aarch64 进行交叉编译时(尽管目标具有完整的 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,并且ménage à trois 是亲密的。事实上,gcc 是用libc 在复杂的do-si-do 中使用ld构建的。请参阅 Preshing on Programming 的 great guide 中的此示例:

强制分离和link to other libraries是可以的,但并不容易。

例如,您使用的链接器具有一组 默认搜索目录,这些目录已嵌入其中。来自fine manual

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

而且它变得更加紧密。默认情况下,gcc 将调用位置是硬编码的 动态链接器。对于交叉编译器,它可能类似于/lib/ld-linux-aarch64.so.1。不仅如此,可执行文件也可能以硬编码路径结束,如其program interpreter

同样,如果你小心的话,你可以拆开工具链和override things。但不仅执行起来很棘手,特别是如果你有一个复杂的构建,选项和路径的多种组合意味着通常还有bugs。所以你的宿主环境很容易泄漏到你的交叉编译工具链中。

总之,交叉编译需要一个工具链。虽然从包管理器中提取交叉编译器似乎是一件容易且合法的事情,但它带来了很多隐含的包袱。您可以仔细按照包依赖项检查您获得的版本,或者使用许多专用工具链环境之一,例如crosstool-NG

【讨论】:

    猜你喜欢
    • 2018-07-21
    • 2012-05-14
    • 2018-11-19
    • 1970-01-01
    • 2012-06-01
    • 2013-04-03
    • 1970-01-01
    • 2020-12-07
    • 2018-12-19
    相关资源
    最近更新 更多