针对 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
(Tier 1)x86_64-unknown-linux-gnu
(Tier 1)x86_64-unknown-linux-musl
(Tier 2,含主机工具)powerpc-unknown-linux-gnu
(Tier 2,含主机工具)powerpc64-unknown-linux-gnu
(Tier 2,含主机工具)s390x-unknown-linux-gnu
(Tier 2,含主机工具)
以下目标不受影响,因为它们已经有更高的 glibc/内核要求
aarch64-unknown-linux-gnu
(Tier 1)aarch64-unknown-linux-musl
(Tier 2,含主机工具)arm-unknown-linux-gnueabi
(Tier 2,含主机工具)arm-unknown-linux-gnueabihf
(Tier 2,含主机工具)armv7-unknown-linux-gnueabihf
(Tier 2,含主机工具)mips-unknown-linux-gnueabihf
(Tier 2,含主机工具)powerpc64le-unknown-linux-gnueabihf
(Tier 2,含主机工具)riscv64gc-unknown-linux-gnueabihf
(Tier 2,含主机工具)
对于没有分发 Rust 工具链的其他 tier 2 或 tier 3 目标,我们不会准确跟踪最低要求,并且它们可能受此更改影响,也可能不受影响。*-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 可以使用更新的系统调用,而无需维护和测试与不支持这些系统调用的内核的兼容性。
新的基准要求是根据仍然活跃支持的长期支持发行版中的最低共同标准选择的。目前这是具有 glibc 2.17 和内核 3.10 的 RHEL 7。内核要求选择 3.2,因为这是 glibc 本身的最低要求,并且这些版本之间相关的 API 差异很小。
我该怎么办?
如果您或您的组织受到此更改的影响,根据您的情况,有几种可行的选择
- 升级您的目标系统,或提高您软件的最低要求,以满足新的限制。
- 如果您在旧主机上运行 Rust 编译器,考虑改用较新的主机进行交叉编译。
- 如果您针对旧的 glibc 版本,考虑改用 musl 作为目标。
- 如果您针对旧的内核版本并使用了 libstd,您可能面临困难:在这种情况下,您可能需要冻结您当前的 Rust 版本,或维护一个支持旧内核的 libstd 分支。