LWN:关于用GCC编译Rust的最新情况!
关注了就能看到更多这么棒的文章哦~
Compiling Rust with GCC: an update
By Jonathan Corbet
September 9, 2022
Kangrejos
DeepL assisted translation
https://lwn.net/Articles/907405/
虽然 Rust 语言对内核开发来说挺有吸引力的,但许多开发者看到只有一个编译器,就感到比较担忧;有许多理由表明应该要有第二个实现。在 2022 年的 Kangrejos 聚会上,三位开发者介绍了用 GCC 来编译 Rust 程序的项目,使用了两种不同的方式。要想拥有一个功能齐全、基于 GCC 的 Rust 仍然需要一些时间,但正在快速取得进展。
gccrs
Philip Herron 和 Arthur Cohen 首先介绍了 gccrs,它是 GCC 编译器的一个 Rust 前端。Herron 说,这个项目最初是在 2014 年启动的,不过后来停滞不前了。在 2019 年的时候重新启动,进展缓慢,直到足以支撑两位开发者的资金到账之后情况才发生改变,这要感谢 Open Source Security and Embecosm。从那时起,开发的速度就快多了。
目前,开发人员的目标是 Rust 1.49,这有点落后于最新的技术水平,毕竟这个版本是在 2020 年底发布的。目前来说在某些方面,开发者甚至还在追赶这个老版本;例如,还缺少一些 intrinsics。而在其他方面,他们则试图走到领先地位,比如在 const generics 方面已经做了一些工作,目前为止它实际上只是完成了一个 parser,"但它是一个开始"。作为 GCC 的一部分,gccrs 的实验性发布可望在 2023 年 5 月或 6 月提供出来。
Cohen 特别谈到了 Rust for Linux 项目(Rust 与 Linux 内核的整合)的编译工作。该项目目前的目标是 Rust 1.62,这比 gccrs 的目标 1.49 要新得多;因此,即使 gccrs 达到了目标,也有相当多的地方需要补上去。他说,语言本身的差异并不大,但库的差异较大。哪怕是使用官方编译器,Rust for Linux 也必须设置 RUST_BOOTSTRAP 变量从而使用一些 unstable feature;gccrs 正试图在实现内核所需的功能。Generic associated types 也是必需的。最终,我们的目标是让 gccrs 能够完成 Rust for Linux 的编译。
他指出了一点,gccrs 并没有试图实现跟现有的 rustc 编译器所使用的完全相同的编译器标志(compiler flags)。这些实现工作会是非常艰巨的任务,而且他们 "不符合 GCC 的风格"。开发者正在为 Cargo build 系统来实现一个单独的 wrapper,使其能够调用 gccrs 来取代 rustc。
内核的一个重要组成部分(其实也就是所有一切了)就是 libcore 库。比如说,它包括像 Option 和 Result 这样的基本类型,没有这些类型就什么都不能做了。另外还需要 liballoc 库,它实现了 Vector 和 Box 等类型。Cohen 指出,这个库已经为内核进行了定制,但 Rust for Linux 开发者 Miguel Ojeda 说,这些改动很小。
目前都是通过用 gccrs 编译各种项目来进行测试的;这些项目包括 Blake3 crypto library 和 libcore 1.49。rustc test suite 也被使用了。后续计划要把 Rust for Linux 的编译也加入到测试集合中。
目前还缺少什么?Herron 说,在目前的 gccrs 中,borrow checking 是一个很主要的缺失功能。Opaque types 还没有实现。另外,当然,还有很多 bug。Cohen 补充说,test suite 方面还需要不少工作。很多测试都是应该要 fail 的,所以 gccrs "能通过" 这些测试,但实际上不是按照期望的原因来通过测试的。他正在努力修改从而正确地使用错误代码,以便只有正确的失败才被判定为合理行为。
未来的计划包括大量的交叉编译的测试。最终,如果能开始用 Crater 进行测试就会很好了,它可以编译 crates.io 上的所有 crates,但这将需要更长时间。关于 borrow checking,Cohen 补充说,他们甚至没有尝试来进行自己的实现;相反,他们计划整合 Polonius。希望这预示着未来可以跟 Rust 社区有更多的代码共享。
代码库可以在 GitHub 上看到。
rust_codegen_gcc
Antoni Boucher 随后介绍了他的项目的最新情况,该项目名为 rust_codegen_gcc。他开始说,rustc 编译器是建立在 LLVM 之上的,但它包括了一个 API,允许替换不同的后端来生成代码。这个 API 可以用来把 libgccjit 用在 rustc 中,从而实现使用 GCC 生成代码。这项工作的最大动力是可以支持 LLVM 无法编译的架构。这对于 Rust for Linux 能支持内核支持的所有架构是有必要的,而且对于其他嵌入式编译对象也应该是有用的。
在过去的一年中,rust_codegen_gcc 已经被合并到 rustc 仓库中。它已经获得了对全局变量和 128 位整数的支持(尽管还不支持 big-endian 格式)。对 SIMD 操作的支持也有所改善,目前可以编译 x86-64 的 tests 并且大多数都能通过。现在也可以用 rust_codegen_gcc 来引导 rustc,这是一个很大的里程碑。但有些程序还不能编译。alignment 支持也有所改善,支持了 packed struct,内联汇编的支持也越来越好,并且支持一些函数和变量属性。Boucher 增加了许多 GCC 所缺乏的 intrinsics,并修复了许多 crash 的问题。
现在几乎所有的 rustc 测试都通过了,而且情况越来越好;大多数错误都是与 SIMD 或未实现的功能如链接时间优化(LTO, link-time optimization)有关的。关于 SIMD,必须要添加到 libgccjit 的功能已经完成了,"vector shuffle" 指令也是如此。大约 99% 的 LLVM SIMD intrinsics 和大约一半的 Rust SIMD intrinsics 已经完成了实现。已经有大量的 fix 和改进(例如 128 位整数支持)已经随着这项工作进入了 GCC。
当然,还有很多事情要做。目前尚未完结的任务包括要支持 panic()、正确的 debuginfo、LTO、以及 128 位的 big-endian 整数支持。对新架构的支持必须添加到函数库中,对 SIMD 的支持需要扩展到 X86 之外的平台。还有一些函数和变量属性也有待于实现,包括 inline 支持。也计划能够通过 rustup 来进行发布。
在 rustc 的 API 中,还有许多东西可以改进。例如,GCC 区分了 lvalues(赋值的目标)和 rvalues,而 LLVM 只有 "values";这些不匹配的地方就带来了一些困难。LLVM 有一个关于 exception 的 "landing pad" 的概念,而 GCC 使用的是 try/catch 机制。对 basic block 的处理在 API 中是隐含的(implicit),但在某些地方需要明确标出(explicit)。从更基本的角度来说,GCC 的 API 是基于抽象语法树(abstract syntax tree)的,而 LLVM 的 API 是基于指令(instruction)的,有时会导致混淆。LLVM 对 struct 和 array 使用了相同的聚合操作(aggregate operations),而在 GCC 中就不是这样。
在 libgccjit 方面,包括 attribute 在内的 type introspection (类型自省)还有待改进。用在完成代码生成所需的时间,以及产生的二进制文件的 size,都比 LLVM 差。libgccjit 也有一些优化还没有加进来。
Boucher 演示了使用 GCC 后端的编译器来编译一些基本的 Rust 内核模块的过程。Wedson Almeida Filho 询问是否对 LLVM 不支持的架构进行过测试,回答是目前还没有做过。Boucher 说,在进行这种测试时,可能会有 "不少细节需要处理"。
对于 Rust for Linux 来说,还有一些潜在的比较复杂的情况。生成的代码所使用的 ABI 在一些平台上是不一样的。还有一个问题是,是否应该进行 backport 来支持旧版本的编译器。由于需要对 GCC 打补丁才能让 rust_codegen_gcc 正常工作,这就带来了不少复杂性。
Herron 和 Cohen 在会议结束时也加入了进来跟 Boucher 一起回答问题,人们问他们的时间表。Herron 回答说,gccrs 需要一年的时间才能达到 rust_codegen_gcc 现在的水平。当被问及编译时间时,Cohen 说,现在的比较是没有意义的,因为现在的重点仍然是让东西能工作起来。他预计 gccrs 目前 "估计会非常慢"。Boucher 说,rust_codegen_gcc 比 rustc 慢,但还有一些优化工作要做,可以改善这种情况。
[感谢 LWN 用户支持编者参加这次活动]。
全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~