使用gccrs编译Linux内核的进展

Lobsters Hottest 工具

摘要

gccrs项目致力于为GCC开发Rust前端,近期在编译Linux内核方面取得进展,解决了属性处理、名称解析和资源管理中的问题,并重新组织了开发里程碑。

<p><a href="https://lobste.rs/s/cpyuub/progress_toward_compiling_linux_with">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/07/30 19:54

# 使用 gccrs 编译 Linux 的进展 来源:https://lwn.net/SubscriberLink/1083202/f1ba926cd57ac5c5/ ## \[LWN 订阅者专享内容\] `gccrs` 项目 (https://rust-gcc.github.io/) 致力于为 GCC 编译器创建 Rust 前端,在 2026 年上半年将重点放在编译 Linux 内核上。通过用内核 crate 测试编译器,开发团队在为目标 Rust 程序生成正确代码方面取得了显著进展。如项目[周报](https://github.com/Rust-GCC/Reporting/tree/main/2026)和[月报](https://rust-gcc.github.io/#status-reports)所述,这项工作发现并解决了属性处理(详见[二月报告](https://rust-gcc.github.io/2026/03/10/2026-02-monthly-report.html))、名称解析和资源管理(详见[五月报告](https://rust-gcc.github.io/2026/06/02/2026-05-monthly-report.html))等方面的问题。目前,编译器只能处理简单的独立程序,但这种情况在未来几个月内可能迅速改变。 > **没有人比 LWN 更了解 Linux 内核**;通过一个月的试用订阅 (https://lwn.net/Promo/Kernel-2/claim) 掌握最新动态,无需信用卡。 驱动编译 Linux 内核的 Rust 组件源于 Rust 引入内核带来的新工具链需求。目前,开发者必须使用基于 LLVM 的 `rustc` 编译器(尽管 `rustc` 确实有通过 `rust_codegen_gcc` (https://github.com/rust-lang/rustc_codegen_gcc#wip-libgccjit-codegen-backend-for-rust) 将 GCC 作为后端的实验性、进行中的支持)。虽然内核支持 LLVM,但为了支持 LLVM 未覆盖的架构并与 GCC 现有的插件生态系统集成,基于 GCC 的替代方案是必要的。随着内核 Rust 集成的成熟,工具链灵活性和基于 GCC 的编译器的可用性已成为 Linux 发行版的优先事项。 #### 重组里程碑 编译器前端项目通常根据其后端目标的发布周期来跟踪进度。在其 [2026 年 3 月报告](https://rust-gcc.github.io/2026/04/13/2026-03-monthly-report.html)中,`gccrs` 团队宣布了项目管理上的变更,选择将其工作组织为三个基于能力的里程碑,而不是针对特定的 GCC 版本。 第一个里程碑是“嵌入式 Rust 编译器”,能够编译仅依赖 `core` crate (https://rust.docs.kernel.org/core/index.html) 的 `no_std` (https://docs.rust-embedded.org/book/intro/no-std.html) 程序。第二个是“用于 Linux 的 Rust 编译器”,支持 `alloc` crate (https://rust.docs.kernel.org/kernel/alloc/index.html) 以及内核使用的特定 crate。最后一个里程碑是“通用编译器”,旨在处理内核环境之外的更广泛的 Rust 应用。 第一个里程碑尚未完全实现,但已接近完成。针对“用于 Linux 的 Rust”里程碑的工作正在进行中。三月,团队增加了对 `compiler_builtins` (https://crates.io/crates/compiler_builtins) 的支持,这是内核构建所需的关键底层 crate,并专注于解决内核 `ffi` crate (https://crates.io/crates/ffi) 中的问题。为了支持这项工作,Zhi Heng 于 2026 年 5 月加入项目,参与 [Open Source Security](https://opensrcsec.com/) 实习。他的工作致力于修复 `gccrs` 编译内核 crate 时遇到的错误,并建立持续集成测试以防止回归。 然而,仅仅测试编译器能否处理 Rust 代码而不崩溃只是任务的一部分。生成的代码还必须正确。Rust 析构语义的实现对于生成正确代码至关重要,因为习惯用法的 Rust 代码比传统 C 代码更频繁地使用析构,因此这也是另一个重点领域。 #### Drop 基础设施 Rust 使用一种称为“资源获取即初始化”(https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization) (RAII) 的基于作用域的模型来管理资源。当一个值离开作用域时,编译器会自动插入对其析构函数的调用,该析构函数由 `Drop` trait (https://doc.rust-lang.org/std/ops/trait.Drop.html) 定义。 在 Rust 中,跟踪变量何时必须清理是复杂的,因为变量的初始化状态可能会根据函数内的控制流而改变。如果变量被有条件地移动或仅部分初始化,编译器不能简单地在封闭作用域结束时丢弃它。为了解决这个问题,前端必须分析控制流图并生成动态的“drop 标志”——在运行时跟踪的布尔变量——以记录在将此表示传递给 GCC 后端之前是否需要销毁某个值。这一分析在 `gccrs` 中最初的 `Drop` 实现中缺失,导致一些 `Drop::drop()` 调用被省略或不正确。 在 Linux 内核的上下文中,缺失的 `Drop` 调用会导致严重的运行时故障,例如内存泄漏或系统资源未释放。一个典型的例子是锁管理。当内核代码获取锁时,用于 Linux 的 Rust API 会返回一个 `MutexGuard`。该 guard 的 `Drop` 实现负责释放锁。 正如团队在五月份指出的,没有正确的 `Drop` 调用,锁永远不会被释放。这会导致代码编译错误,锁在其 guard 超出作用域后仍然保持,可能引起同步失败或死锁。Google Summer of Code (GSoC) 参与者 Janet Chien 于五月加入该项目,专门专注于构建 `gccrs` 的 `Drop` 基础设施。 #### 名称解析工作 用标准库和内核 crate 测试编译器也暴露了 `gccrs` 处理名称解析方面存在根本性错误,尽管项目已经意识到了其中许多问题,并且早在 2023 年就已开始专门处理名称解析问题。 Rust 维护三个不同的命名空间:值命名空间(用于函数和静态变量)、宏命名空间以及类型命名空间(用于结构体、模块和 trait)。当编译器遇到一个“路径”——一串标识符,如 `crate::foo::bar`,用于引用某个项——它必须为路径的每个段确定正确的命名空间。 开发团队发现其处理流程中存在一个缺陷。以前,当 `gccrs` 查找某个项的定义时,它在目标项类型的命名空间中解析路径。例如,在查找函数时,它在值命名空间中解析路径段。这种方法是不正确的,因为模块和公开可见的导入实际上存在于类型命名空间中;编译器无法在不首先在类型命名空间中解析模块结构本身的情况下,成功地遍历路径以找到函数。 修复此问题需要重写内部数据结构,并重构整个代码中使用的访问者实现。到五月份,这些更改使得 `core` crate 中深度嵌套的导入能够正确解析。模块和导入现在被正确地插入到类型命名空间中,使 `gccrs` 更接近 `rustc` 的行为。 #### 元数据和属性处理 转向编译内核 crate 凸显了 `gccrs` 处理编译器属性和 crate 元数据方面的进一步问题。 Rust 依赖 `#[cfg()]` 等属性进行条件编译。2026 年 2 月的报告描述了首席开发者 Pierre-Emmanuel Patry 如何重构了属性处理管道。他的[工作](https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=49aae3a1ae302dd979c503db8dee56c8c378838b)将移除 `cfg` 属性排除的项的编译器过程拆分为两个不同的阶段。这种分离是必要的,以支持内核中的不稳定特性;其中一些特性依赖于宏展开或条件属性,这些属性必须在主属性验证阶段能够安全地评估它们之前被剥离,否则会触发编译器错误。 三月,`gccrs` 增加了一个命令行选项,等同于 `rustc` 的 `-Zcrate-attr`,称为 `-frust-crate-attr`。此选项允许构建系统在编译器调用期间注入属性,而无需修改底层源文件。这对于传递 `#![no_core]` 属性特别有用,该属性是编译不依赖标准 `core` 库的代码所必需的。那些正对编译器进行模糊测试以发现边缘案例错误的开发者依赖于这个特性。 链接内核的 Rust crate 最终揭示了一个新错误。Rust crate 导出元数据(通常打包在 `.rlib` 文件中),以将其公共 API 传达给其他 crate。在尝试链接内核代码时,开发人员发现某些模块和导出在发出的元数据中完全缺失。由于编译器在元数据生成期间忽略了嵌套模块的导出,`gccrs` 无法解析外部依赖。 这个问题没有被项目现有的元数据测试用例捕获,因为这些测试依赖较扁平的模块结构。识别这个错误需要编译真实世界的代码。因此,团队开始对元数据处理系统进行重大重构,以确保 GNU 工具链能够成功链接内核的依赖树。 #### 当前能力与上游化挑战 那么,`gccrs` 目前能做什么?目前,编译器可以成功处理独立的 `no_core` 程序,并在处理 `core` crate 和实现编译器内置函数方面取得了重大进展。然而,完全编译内核复杂的 Rust 抽象仍然在进行中。`gccrs` 目前能够解析内核代码,项目正专注于正确实现运行时语义。 除了技术障碍,`gccrs` 还必须应对 GNU 工具链的组织挑战。历史上,该项目在将其补丁落地到上游 GCC 树方面面临问题。将全新、快速演进的语言前端集成到 GCC 中是一项巨大的工程,补丁集的大小有时会令上游 GCC 审查者有限的带宽不堪重负。随着前端架构趋于稳定,情况有所改善,但合并大规模更改——例如最近的名称解析重写和 `Drop` 基础设施——仍然需要大量的协调和耐心才能通过上游审查流程。更大的变化是最近有两位 `gccrs` 开发者被提升为 GCC 维护者,这使他们能够在自己的树中暂存更新,然后整体推送。 #### 下一步 针对编译内核所需的其他组件的工作仍在继续。GSoC 参与者 Enes Çevik 也于五月加入项目,正在实施对 `alloc` (https://doc.rust-lang.org/alloc/) crate 的支持。此 crate 处理动态内存分配类型,如 `Box` (https://doc.rust-lang.org/alloc/boxed/struct.Box.html)、`Rc` (https://doc.rust-lang.org/alloc/rc/struct.Rc.html) 和 `Vec` (https://doc.rust-lang.org/alloc/vec/struct.Vec.html)。尽管内核开发避免了许多标准库抽象,但几个核心内核 Rust 抽象依赖于分配类型,因此对 `alloc` crate 的支持是“用于 Linux 的 Rust”里程碑的一个硬性前提。 更广泛的开发社区很快将更近距离地了解这一进展。Patry 和 Arthur Cohen 计划在今年晚些时候在蒙特利尔的 RustConf (https://rustconf.com/) 和巴塞罗那的 EuroRust (https://eurorust.eu/) 上发表题为“使用 gccrs 编译 Linux 内核”的演讲。通过系统地解决内核代码的特定要求,该项目正稳步地为使用 GCC 在 Linux 内核生态系统中编译 Rust 代码奠定基础。 本文索引条目 客座文章 (https://lwn.net/Archives/GuestIndex/) Aromal, Arshal (https://lwn.net/Archives/GuestIndex/#Aromal_Arshal)

相似文章

crustc: 整个rustc编译器,已翻译成C语言

Lobsters Hottest

一个名为cilly的Rust到C编译器工具链已成功将整个rustc编译器翻译成4600万行C代码,生成了一个可以用GCC构建的功能性Rust编译器。该项目旨在通过生成可移植的C代码,使Rust能够在老旧/冷门硬件上运行。

使用并行Claude团队构建C编译器

Anthropic Engineering

Anthropic研究员展示了如何使用16个并行Claude实例自主构建一个基于Rust的C编译器,该编译器能够编译Linux内核。文章详细介绍了这一多智能体自主编码实验的架构、成本和经验教训。

我们的Rust到Zig重写进展如何

Lobsters Hottest

Roc编译器团队已将他们30万行Rust代码库重写为Zig,经过18个月实现了功能对等,生成了更小的WebAssembly二进制文件并提高了性能。