[LWN subscriber-only content]

Welcome to LWN.net

The following subscription-only content has been made available to you by an LWN subscriber. Thousands of subscribers depend on LWN for the best news from the Linux and free software communities. If you enjoy this article, please consider subscribing to LWN. Thank you for visiting LWN.net!

July 28, 2026

This article was contributed by Arshal Aromal

The gccrs project, which is creating a Rust frontend for the GCC compiler, has spent the first half of 2026 focusing on compiling the Linux kernel. By testing the compiler against the kernel crates, the development team has made significant progress toward generating correct code for other Rust programs. As detailed in the project's weekly and monthly reports, this effort has uncovered and resolved problems in areas such as attribute handling (described in the report for February), name resolution, and resource management (both detailed in the May report). Currently, the compiler can only handle simple standalone programs, but that situation could change rapidly in the coming months.

The drive to compile the Rust components of the Linux kernel stems from the new toolchain requirements brought by Rust's introduction into the kernel. Currently, developers must use the LLVM-based rustc compiler (although rustc does have experimental, in-progress support for using GCC as a backend via rust_codegen_gcc). While LLVM is supported by the kernel, a GCC-based alternative is necessary to support architectures not targeted by LLVM and to integrate with GCC's existing plugin ecosystem. As the kernel's Rust integration matures, toolchain flexibility and the availability of a GCC-based compiler have become priorities for Linux distributions.

Reorganizing milestones

Compiler frontend projects often track their progress against the release cycle of their target backend. In its March 2026 report, the gccrs team announced a change in project management, opting to organize its work into three capability-based milestones rather than targeting specific GCC versions.

The first milestone is an "embedded Rust compiler" capable of compiling no_std programs that depend only on the core crate. The second is a "Rust for Linux compiler" that supports the alloc crate alongside the specific crates used by the kernel. The final milestone is a "general purpose compiler" aimed at handling broader Rust applications beyond the kernel environment.

The first milestone is not completely implemented, but it is close. Progress toward the Rust for Linux milestone is underway. In March, the team added support for compiler_builtins, a key low-level crate required by kernel builds, and focused on resolving problems within the kernel's ffi crate. To support this effort, Zhi Heng joined the project in May 2026 for an Open Source Security internship. His work is dedicated to fixing bugs encountered when gccrs compiles kernel crates and establishing continuous-integration testing to prevent regressions.

However, simply testing to ensure the compiler can process Rust code without crashing is only part of the task. The generated code must also be correct. The implementation of Rust's destructor semantics is key to the generation of correct code, because idiomatic Rust code uses them more heavily than traditional C code, so that has been another area of focus.

The Drop infrastructure

Rust manages resources using a scope-based model known as resource acquisition is initialization (RAII). When a value goes out of scope, the compiler automatically inserts a call to its destructor, which is defined by the Drop trait.

In Rust, tracking when variables must be cleaned up is complex because a variable's initialization state can change depending on the control flow within a function. If a variable is conditionally moved or only partially initialized, the compiler cannot simply drop it at the end of the enclosing scope. To solve this, the frontend must analyze the control-flow graph and generate dynamic "drop flags"—boolean variables tracked at run time—to record whether a value needs to be destroyed before passing this representation to the GCC backend. That analysis was missing from the initial implementation of Drop in gccrs, causing some Drop::drop() calls to be omitted or incorrect.

In the context of the Linux kernel, missing Drop calls lead to severe run-time failures, such as memory leaks or unreleased system resources. A primary example is lock management. When kernel code acquires a lock, the Rust for Linux API returns a MutexGuard. The Drop implementation for this guard is responsible for releasing the lock.

As the team noted in May, without proper Drop calls, the lock is never released. This results in miscompiled code where locks remain held after their guard goes out of scope, which can cause synchronization failures or deadlocks. Google Summer of Code (GSoC) participant Janet Chien joined the project in May to focus specifically on building the gccrs Drop infrastructure.

Name-resolution work

Testing the compiler against the standard library and kernel crates also exposed highlighted fundamental bugs in how gccrs handled name resolution, although the project was already aware of many of them, and had begun working on name-resolution in particular in 2023.

Rust maintains three distinct namespaces: the value namespace for functions and static variables, the macro namespace, and the type namespace for structures, modules, and traits. When the compiler encounters a "path"—a sequence of identifiers like crate::foo::bar used to refer to an item—it must identify the correct namespace for each segment of the path.

The development team discovered a flaw in its processing pipeline. Previously, when gccrs looked for the definition of an item, it resolved paths within the namespace of the target item type. For instance, when looking for a function, it resolved the path segments in the value namespace. This approach is incorrect because modules and publicly visible imports actually live in the type namespace; the compiler cannot successfully traverse a path to find a function without first resolving the module structure itself in the type namespace.

Fixing this problem required a rewrite of internal data structures and a refactoring of the visitor implementations used throughout the code. By May, these changes allowed the deeply nested imports in the core crate to resolve correctly. Modules and imports are now properly inserted into the types namespace, aligning gccrs more closely with rustc behavior.

Metadata and attribute handling

The shift to compiling kernel crates highlighted further problems in how gccrs processes compiler attributes and crate metadata.

Rust relies on attributes, such as #[cfg()], for conditional compilation. The February 2026 report, described how lead developer Pierre-Emmanuel Patry had reworked the attribute-handling pipeline. His work split, into two distinct passes, the compiler pass that removes items excluded by the cfg attribute. This separation was necessary to support unstable features within the kernel; some of these features rely on macro expansion or conditional attributes that must be stripped before the main attribute-validation pass can safely evaluate them without triggering compiler errors.

In March, gccrs added a command-line option equivalent to rustc's -Zcrate-attr, called -frust-crate-attr. This option allows the build system to inject attributes during compiler invocation without modifying the underlying source files. This is particularly useful for passing the #![no_core] attribute, which is necessary to compile code without depending on the standard core library. That feature is relied upon by developers who are fuzzing the compiler to locate edge-case bugs.

Linking the kernel's Rust crates eventually revealed a new bug. Rust crates export metadata, typically bundled in .rlib files, to communicate their public APIs to other crates. When attempting to link kernel code, the developers found that certain modules and exports were simply missing from the emitted metadata. Because the compiler was omitting nested module exports during metadata generation, gccrs was unable to resolve external dependencies.

This problem was not caught by the project's existing metadata test cases, which relied on flatter module structures. Identifying this bug required compiling real-world code. Consequently, the team began a significant rework of the metadata handling system to ensure the GNU toolchain can successfully link the kernel's dependency tree.

Current capabilities and the challenges of upstreaming

So, what is possible for gccrs today? Currently, the compiler can successfully handle standalone no_core programs, and has made significant strides in processing the core crate and implementing compiler builtins. However, fully compiling the kernel's complex Rust abstractions remains a work in progress. gccrs is currently able to parse the kernel's code and the project is focused on correctly implementing the run-time semantics.

Beyond technical hurdles, gccrs has also had to navigate the organization challenges of the GNU toolchain. Historically, the project has faced problems landing its patches in the upstream GCC tree. Integrating an entirely new, rapidly evolving language frontend into GCC is a large undertaking, and the size of the patch sets has occasionally overwhelmed the limited bandwidth of upstream GCC reviewers. While the situation has improved as the frontend's architecture has stabilized, merging sweeping changes—such as the recent name-resolution rewrites and Drop infrastructure—still requires significant coordination and patience to clear the upstream review process the bigger change is the recent elevation of two gccrs developers to the status of GCC maintainers, which allows them to stage updates in their own tree and then push them wholesale.

Next steps

Work continues on the remaining components required to compile the kernel. GSoC participant Enes Çevik, who also joined the project in May, is implementing support for the alloc crate. This crate handles dynamic memory allocation types like Box, Rc, and Vec. Although kernel development avoids many standard library abstractions, several core kernel Rust abstractions rely on allocation types, making support for the alloc crate a hard prerequisite for the "Rust for Linux" milestone.

The broader development community will soon receive a closer look at this progress. Patry and Arthur Cohen plan to present a talk titled "Compiling the Linux kernel with gccrs" at RustConf in Montreal and EuroRust in Barcelona later this year. By systematically addressing the specific requirements of kernel code, the project is steadily building the foundation for using GCC to compile Rust code within the Linux kernel ecosystem.


Index entries for this article
GuestArticlesAromal, Arshal