crustc: Entirety of rustc, translated to C

crustc: Entirety of rustc, translated to C

crustc - rustc 1.98.0-nightly (c712ea946 2026-06-16), converted to 46 million lines of C. This is a functional Rust compiler you can build with GCC & make. crustc - rustc 1.98.0-nightly (c712ea946 2026-06-16),被转换为 4600 万行 C 代码。这是一个你可以使用 GCC 和 make 构建的功能性 Rust 编译器。

We need to provide a path to LLVM(libLLVM.so.22.1-rust-1.98.0-nightly) # I could include pre-built LLVM in the project, but I’d rather not embed random binaries in the project.

我们需要提供 LLVM 的路径 (libLLVM.so.22.1-rust-1.98.0-nightly) # 我本可以将预构建的 LLVM 包含在项目中,但我不想在项目中嵌入随机的二进制文件。

make -j20 LLVM_LIB_DIR=~/.rustup/toolchains/nightly-2026-06-16-aarch64-unknown-linux-gnu/lib (执行构建命令)

It is just C code [1], which, when compiled, gives you a functional Rust compiler. 这仅仅是 C 代码 [1],编译后就能得到一个功能完备的 Rust 编译器。

It works - (library path to point to libLLVM.so.22.1-rust-1.98.0-nightly - rustc uses llvm)

它成功运行了 - (库路径指向 libLLVM.so.22.1-rust-1.98.0-nightly - rustc 使用了 llvm)

LD_LIBRARY_PATH=~/.rustup/toolchains/nightly-2026-06-16-aarch64-unknown-linux-gnu/lib:./rustc_driver ./rustc/rustc —version rustc 1.98.0-nightly (c712ea946 2026-06-16) (执行版本检查命令)

That Rust compiler can compile code - build core, alloc, std - you name it! 这个 Rust 编译器可以编译代码——构建 core、alloc、std——应有尽有!

What is this? This is a demo/teaser for my new Rust to C compiler toolchain. The full cilly toolchain compiles your own Rust to C for arbitrary targets. This repo just shows the compiler compiling itself, as I believe this is the flashiest showcase I could do. 这是什么?这是我新的 Rust 转 C 编译器工具链的演示/预告。完整的 cilly 工具链可以将你自己的 Rust 代码编译为任意目标的 C 代码。这个仓库仅展示了编译器编译其自身的过程,因为我认为这是我能做的最炫酷的展示。

How was this done? For the past 3 years, I have been working on compiling Rust to C. I made a few public attempts, like rustc_codegen_clr, and a lot of private ones. This is, by my count, the 14th attempt: cilly. It is a Rust library for generating C code and a Rust compiler backend (read: plugin) that allows you to compile Rust to C. 这是如何实现的?在过去的 3 年里,我一直致力于将 Rust 编译为 C。我做过几次公开尝试,比如 rustc_codegen_clr,还有很多私下的尝试。据我统计,这是第 14 次尝试:cilly。它是一个用于生成 C 代码的 Rust 库,也是一个允许你将 Rust 编译为 C 的 Rust 编译器后端(即插件)。

The main innovation behind cilly is that it adapts to C compilers. It can generate “witness” programs, which check what a given compiler and platform support: cilly 背后的主要创新在于它能够适应各种 C 编译器。它可以生成“见证”程序,用于检查给定编译器和平台的支持情况:

/* This compiles if and only if our C compiler supports _Thread_local. / _Thread_local int KEYWORD_TLS_SUPPORTED; / 仅当我们的 C 编译器支持 _Thread_local 时,这段代码才能编译通过。 */

This means Cilly will generate C code, which will make your specific, weird “Shminky C compiler for Blorbo OS” happy. 这意味着 Cilly 将生成能够满足你特定且古怪的“Blorbo OS 的 Shminky C 编译器”要求的 C 代码。

/* This will pass in some C compilers. / assert(sizeof(float) == sizeof(double)); / 这在某些 C 编译器中可以通过。 */

All type layouts, sizes, alignments, character encodings (ASCII), and integer formats (two’s complement) are queried for. With fallbacks, where possible. I try my very best not to assume anything outside of ANSI C[2] - including workarounds for things in “modern” C standards, like strict aliasing. 所有的类型布局、大小、对齐方式、字符编码(ASCII)和整数格式(补码)都会被查询。在可能的情况下提供回退方案。我尽最大努力不去假设 ANSI C [2] 之外的任何内容——包括针对“现代”C 标准中某些特性(如严格别名规则)的变通方法。

Sadly, this means the output of cilly is compiler-specific (i.e., you can’t take the cilly C generated for Arm64 and run it on riscv32, but you can generate cilly C specifically for riscv32). This build of rustc (the generated C) is “targeting” ARM64 Linux because that is the ISA of my workstation. 遗憾的是,这意味着 cilly 的输出是特定于编译器的(即,你不能拿为 Arm64 生成的 cilly C 代码去 riscv32 上运行,但你可以专门为 riscv32 生成 cilly C 代码)。这个 rustc 构建版本(生成的 C 代码)是“针对” ARM64 Linux 的,因为这是我工作站的指令集架构。

Why was this done? The primary goal of this is support for old/obscure hardware with no LLVM/GCC support. There are still some systems out there that don’t support Rust but support C. Whenever some project moves from Rust to C, or a Rust alternative of a C project is made, support for those targets is validly raised as a downside of Rust [3]. The goal of this project is to remove that problem. 为什么要这样做?其主要目标是支持那些没有 LLVM/GCC 支持的旧式/冷门硬件。目前仍有一些系统不支持 Rust 但支持 C。每当有项目从 Rust 迁移到 C,或者创建了 C 项目的 Rust 替代品时,对这些目标平台的支持往往被合理地视为 Rust 的一个缺点 [3]。该项目的目标就是消除这个问题。

cilly wraps rustc and a C compiler and translates the Rust code to C on the fly. From the user perspective, this is as simple as defining what C compiler to use for a given target. cilly 封装了 rustc 和 C 编译器,并实时将 Rust 代码转换为 C。从用户的角度来看,这就像为给定目标定义使用哪种 C 编译器一样简单。

“triple”: [ “sdcc_z180-unknown-none” ], “tool_def”: { … } (配置示例)

Network transparency. cilly is network transparent, and can talk to C compilers over TCP (may be extended to weird things like UART if need be). This is a solution to the bootstrap paradox / platforms without C cross compilers. You build a small C server on your Blorbo OS, run rustc on some normal platform like Linux, and let cilly talk over the wire. 网络透明性。cilly 具有网络透明性,可以通过 TCP 与 C 编译器通信(如有必要,可扩展到 UART 等奇怪的接口)。这是解决引导悖论/缺乏 C 交叉编译器的平台的一种方案。你在 Blorbo OS 上构建一个小型 C 服务器,在 Linux 等普通平台上运行 rustc,然后让 cilly 通过网络进行通信。

I have successfully used this to compile small Rust programs for x86 Plan9 VMs, while running rustc on Arm64 linux. 我已经成功地使用它为 x86 Plan9 虚拟机编译了小型 Rust 程序,同时在 Arm64 Linux 上运行 rustc。

Generating makefiles. cilly can optionally embed markers within its object files, and save its IR to a cache directory. It can then read those markers, split functions / globals by their definition location, and generate a directory with makefiles - to allow you to build Rust with a C compiler and make. 生成 Makefile。cilly 可以选择在其目标文件中嵌入标记,并将其中间表示(IR)保存到缓存目录中。然后,它可以读取这些标记,按定义位置拆分函数/全局变量,并生成包含 Makefile 的目录——从而允许你使用 C 编译器和 make 来构建 Rust。

ABI compatibility. cilly generated code is mostly ABI compatible with normal rustc compiled code. I say mostly, because on some platforms(… like arm64) rustc choose an ABI not representable from C[4]. ABI 兼容性。cilly 生成的代码在很大程度上与普通 rustc 编译的代码 ABI 兼容。之所以说“很大程度上”,是因为在某些平台(……比如 arm64)上,rustc 选择的 ABI 在 C 语言中无法表示 [4]。

Reproduction Prerequisites 复现前提条件

This rust compiler was built on: uname -a Linux spark-2773 6.17.0-1021-nvidia #21-Ubuntu SMP PREEMPT_DYNAMIC Wed May 27 19:14:05 UTC 2026 aarch64 aarch64 aarch64 GNU/Linux 这个 Rust 编译器构建于:(系统信息)

This is the C compiler I used: readelf -p .comment ./rustc/rustc String dump of section ‘.comment’: [ 1] GCC: (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 [ 2e] Linker: Ubuntu LLD 18.1.3 这是我使用的 C 编译器:(编译器信息)

In order to build the demo, you will need to provide it with the right LLVM libs. The easies way to do so is to just use the LLVM rustc ships: rustup install nightly-2026-06-16 为了构建该演示,你需要提供正确的 LLVM 库。最简单的方法就是直接使用 rustc 自带的 LLVM:(安装命令)

Build With the right GCC(more modern GCC versions should work too, untested), right LLVM version, and GNU make installed, run: 构建 在安装了正确的 GCC(较新的 GCC 版本应该也可以,但未经测试)、正确的 LLVM 版本和 GNU make 的情况下,运行:

We need to provide a path to LLVM(libLLVM.so.22.1-rust-1.98.0-nightly)

I could include pre-built LLVM in the project, but I’d rather not embed random binaries in the project.

make -j20 LLVM_LIB_DIR=~/.rustup/toolchains/nightly-2026-06-16-aarch64-unknown-linux-gnu/lib

我们需要提供 LLVM 的路径 (libLLVM.so.22.1-rust-1.98.0-nightly)

我本可以将预构建的 LLVM 包含在项目中,但我不想在项目中嵌入随机的二进制文件。

(构建命令)

CFLAGS work(CAVEAT: some flags will slow compilation down)

make -j20 CFLAGS=-g

CFLAGS 可以使用(注意:某些标志会减慢编译速度)

(构建命令)

And… voilà! 然后……大功告成!

Compilation speed I strongly recommend not enabling optimizations: both because the may break stuff(this is just a demo, and it’s… ee… rough around the edges[5]) AND because optimizations take time at this scale. Without opts, my machine builds the project in a few minutes: 编译速度 我强烈建议不要开启优化:既是因为它们可能会破坏某些东西(这只是一个演示,而且……呃……还有些粗糙 [5]),也是因为在如此规模下,优化非常耗时。在不开启优化的情况下,我的机器在几分钟内就能构建完成:

make -j20 937.98s user 123.77s system 1352% cpu 1:18.48 total (构建耗时)

With opts, expect to chok 开启优化后,预计会卡住……