提高 glibc 和 Linux 内核要求

2022 年 8 月 1 日 · Nikita Popov

针对 Linux 的 Rust 工具链的最低要求将 提高,从 Rust 1.64.0 版本开始(预计于 2022 年 9 月 22 日发布)。新的最低要求是

  • glibc >= 2.17(之前为 glibc >= 2.11)
  • 内核 >= 3.2(之前为内核 >= 2.6.32)

这些要求适用于运行 Rust 编译器本身(以及 Cargo 或 Rustup 等其他 Rust 工具),以及运行由 Rust 生成的二进制文件(如果它们使用 libstd)。

如果您没有针对旧的长期支持发行版或运行旧版 Linux 版本的嵌入式硬件,则此更改不太可能影响您。否则,请继续阅读!

受影响的目标

原则上,新的内核要求影响所有 *-linux-* 目标,而 glibc 要求影响所有 *-linux-gnu* 目标。实际上,许多目标已经要求更新的内核或 glibc 版本。这些目标的要求不会改变。

在分发 Rust 主机工具链的目标中,以下目标受到影响

  • i686-unknown-linux-gnu(第一层)
  • x86_64-unknown-linux-gnu(第一层)
  • x86_64-unknown-linux-musl(第二层,带主机工具)
  • powerpc-unknown-linux-gnu(第二层,带主机工具)
  • powerpc64-unknown-linux-gnu(第二层,带主机工具)
  • s390x-unknown-linux-gnu(第二层,带主机工具)

以下目标不会受到影响,因为它们已经具有更高的 glibc/内核要求

  • aarch64-unknown-linux-gnu(第一层)
  • aarch64-unknown-linux-musl(第二层,带主机工具)
  • arm-unknown-linux-gnueabi(第二层,带主机工具)
  • arm-unknown-linux-gnueabihf(第二层,带主机工具)
  • armv7-unknown-linux-gnueabihf(第二层,带主机工具)
  • mips-unknown-linux-gnueabihf(第二层,带主机工具)
  • powerpc64le-unknown-linux-gnueabihf(第二层,带主机工具)
  • riscv64gc-unknown-linux-gnueabihf(第二层,带主机工具)

对于其他第二层或第三层目标,我们没有分发 Rust 工具链,因此我们无法准确跟踪最低要求,它们可能会或可能不会受到此更改的影响。*-linux-musl* 目标仅受内核要求影响,不受 glibc 要求影响。仅使用 libcore 而不是 libstd 的目标不受影响。

可以在 平台支持页面 上找到支持目标及其要求的列表。

受影响的系统

用于新基线要求的 glibc 和内核版本已经接近十年了。因此,此更改应该只影响那些针对旧的长期支持 Linux 发行版或运行旧版 Linux 的嵌入式硬件的用户。

以下 Linux 发行版仍然在新的要求下得到支持

  • RHEL 7(glibc 2.17,内核 3.10)
  • SLES 12-SP5(glibc 2.22,内核 4.12.14)
  • Debian 8(glibc 2.19,内核 3.16.7)
  • Ubuntu 14.04(glibc 2.19,内核 3.13)

以下发行版不再在新的要求下得到支持

  • RHEL 6(glibc 2.12,内核 2.6.32)
  • SLES 11-SP4(glibc 2.11.3,内核 3.0.101)
  • Debian 6(glibc 2.11,内核 2.6.32),Debian 7(glibc 2.13,内核 3.2.41)
  • Ubuntu 12.04(glibc 2.15,内核 3.2)

在第二个列表中的发行版中,只有 RHEL 6 仍然有有限的供应商支持(ELS)。

为什么要提高要求?

我们希望 Rust 以及由 Rust 生成的二进制文件尽可能广泛地使用。同时,Rust 项目只有有限的资源来维护与旧环境的兼容性。

工具链要求有两个部分:在主机系统上运行 Rust 编译器的最低要求,以及交叉编译二进制文件的最低要求。

主机工具链的最低要求会影响我们的构建系统。Rust CI 为数十个不同的目标生成二进制工件。创建支持旧版 glibc 版本的二进制文件需要在具有旧版 glibc 的操作系统上构建(对于本地构建)或使用具有旧版 glibc 版本的构建根目录(对于交叉编译构建)。

同时,Rust 依赖于 LLVM 进行优化和代码生成,LLVM 定期提高其工具链要求。LLVM 16 将需要 GCC 7.1 或更高版本(而 LLVM 15 仅名义上支持 GCC 5.1)。随着时间的推移,创建具有非常旧的 glibc 和最新编译器的构建环境变得越来越困难。crosstool-ng(我们用于大多数交叉编译需求)不支持同时针对 glibc 2.11 和使用满足新 LLVM 要求的编译器。

交叉编译二进制文件的要求有不同的动机:它们会影响 libstd 需要支持的内核版本。提高内核要求允许 libstd 使用更新的系统调用,而无需维护和测试与不支持这些系统调用的内核的兼容性。

新的基线要求被选为仍然具有活动支持的长期支持发行版的最小公分母。目前是 RHEL 7,glibc 2.17 和内核 3.10。内核要求被选为 3.2,因为这是 glibc 本身的最低要求,并且这些版本之间几乎没有相关的 API 差异。

我应该怎么做?

如果您或您的组织受到此更改的影响,您可以根据您的情况选择多种可行的方案

  • 升级您的目标系统,或提高您的软件的最低要求,以满足新的约束。
  • 如果您在旧主机上运行 Rust 编译器,请考虑从更新的主机交叉编译。
  • 如果您针对旧版 glibc 版本,请考虑改为针对 musl。
  • 如果您针对旧版内核版本并使用 libstd,您可能无能为力:在这种情况下,您可能必须冻结当前的 Rust 版本,或维护支持旧版内核的 libstd 分支。