提高 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 编译器本身(以及其他 Rust 工具,如 Cargo 或 Rustup),也适用于运行由 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 版本的 buildroot(对于交叉编译的构建)。

同时,Rust 依赖 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 而不是 3.10,因为这是 glibc 本身的最低要求,并且这些版本之间的相关 API 差异很小。

我应该怎么做?

如果此更改影响到您或您的组织,则根据您的情况,有许多可行的选择

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