# crustc: The Rust Compiler Translated to 46 Million Lines of C

> crustc is a functional Rust compiler built by translating rustc 1.98.0-nightly to C using the cilly toolchain, which compiles Rust to C for targets without LLVM or GCC support. It is a demonstration of what cilly can produce, not a general-use compiler distribution.

**FractalFir/crustc** — Entirety of `rustc`, translated to C. 

- Repository: https://github.com/FractalFir/crustc
- Stars: 486 · Forks: 12
- Language: C
- License: not declared
- Published: 2026-09-17 · Updated: 2026-09-17 · Language: en
- Canonical page: https://hysenlabs.com/projects/fractalfir-crustc

## What crustc Is and Why It Was Built

crustc is not a new compiler: it is the existing Rust compiler, rustc 1.98.0-nightly, expressed as 46 million lines of C code generated by the cilly toolchain. The repository exists as a demonstration. The author's stated goal is to remove a recurring objection to Rust adoption: that it cannot target platforms where only a C compiler is available.

Some hardware still runs systems that predate LLVM and GCC support. When a project migrates from C to Rust, or when a Rust alternative to a C library is proposed, the inability to compile Rust on those targets is a legitimate barrier. cilly's approach is to wrap rustc and a C compiler so that Rust code is compiled to C first, then compiled to the target with whatever C compiler is available.

crustc demonstrates that this approach works on at least one large, real-world Rust program: the compiler itself. The author describes it as the flashiest showcase for cilly, since building rustc from C is more dramatic than building a small program.

## How cilly Adapts to Any C Compiler

The main technical contribution in cilly is that it does not assume a standard C compiler. Instead, it generates witness programs that probe what the target compiler supports. The README shows an example witness:

```c
/* This compiles if and only if our C compiler supports _Thread_local. */
_Thread_local int KEYWORD_TLS_SUPPORTED;
```

Based on what each witness compiles, cilly generates C code that the specific compiler can handle. This means the generated C for an ARM64 Linux GCC build differs from the generated C for a hypothetical SDCC compiler targeting a Z180 microprocessor. The README includes a JSON configuration example showing how to define a custom target with its compiler executable and arguments.

This compiler-specific output is the main portability trade-off: C generated by cilly for one architecture cannot be reused for another. You must regenerate the C for each target. The upside is that the output is valid for compilers that deviate from standard C in ways that most code generators cannot handle.

## Building crustc from Source

The build requires GCC 13 or later, GNU make, and the LLVM library that rustc ships with, obtained through rustup:

```sh
rustup install nightly-2026-06-16
```

With the LLVM library path in hand, run make with the path as an argument:

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

The README strongly discourages enabling compiler optimizations. Without them, the build completes in roughly 78 seconds on a 20-core ARM64 machine. With optimizations, some larger generated C files cause the compiler to hang or fail.

After the build, verify by running the compiled rustc:

```sh
LD_LIBRARY_PATH=~/.rustup/toolchains/nightly-2026-06-16-aarch64-unknown-linux-gnu/lib:./rustc_driver ./rustc/rustc --version
```

This should print rustc 1.98.0-nightly (c712ea946 2026-06-16). The build target is ARM64 Linux because that is the author's workstation architecture. The generated C cannot be used directly on other architectures.

## Network Transparency for Cross-Compilation

cilly includes a network transparent mode that lets rustc run on one machine while the C compiler runs on another, communicating over TCP. This addresses a bootstrap paradox: if the target system has no C cross-compiler, you cannot build a cross-compiler for it in the first place.

With cilly's network mode, you build a small C server on the target system, run rustc on a normal Linux or macOS machine, and let cilly send compilation jobs over the wire to the remote C compiler. The README confirms this was used successfully to compile small Rust programs for an x86 Plan9 VM while running rustc on ARM64 Linux. The example in the README shows a Plan9 shell session confirming the compiled hello_world binary ran on Plan9.

The README notes that the TCP channel could be extended to other transports, such as UART, which would enable compilation across serial connections. This is a speculative extension rather than a documented feature.

## ABI Compatibility and Known Limitations

Code compiled by cilly is mostly ABI-compatible with code compiled by a standard rustc build. The README uses that qualifier deliberately: on some platforms, including ARM64, rustc chooses calling conventions that are not representable in standard C. In those cases, cilly-compiled code and standard rustc-compiled code cannot be linked together at those boundaries.

The repository is explicitly described as a demo with rough edges. The README's footnote markers suggest there are known issues that are not fully enumerated in the visible text. Enabling optimizations is documented to break things on some files, which means the generated C is not fully correct-by-construction under optimization.

Building the standard library (std, core, alloc) is a separate step, documented in BUILDING_STD.md. Without std, compiled programs cannot use anything from the Rust standard library. The compiler itself prints an error about the missing std crate when you attempt to compile a program without it.

## Makefile-Based Build and Repository Layout

The repository layout is minimal: a Makefile at the root, and four subdirectories: llvm_wrapper/, rustc/, rustc_driver/, and std/. The Makefile builds std and rustc_driver before rustc, since rustc depends on the driver at link time. The clean target recursively removes build artifacts from all subdirectories.

There is no package manager and no build script beyond GNU make. The generated C files are committed to the repository itself, which accounts for the repository's unusually large size. An engineer with GCC, make, and the right LLVM library version can build the project without installing Rust at all, though installing Rust is the easiest way to get the correct LLVM library.

The last push was on 2026-07-02. There are no GitHub releases and no explicit license file, though the README content and its framing as a public demo suggest open access.

## crustc vs. mrustc for Alternative Rust Bootstrapping

mrustc is another project that compiles Rust code without using rustc, by translating Rust to C++. It is used as part of Rust's bootstrap chain to verify that rustc can be rebuilt from scratch. The difference is purpose and approach: mrustc targets Rust bootstrapping from a minimal toolchain and supports a specific older Rust version. cilly and crustc target arbitrary Rust compilation to C for any platform, using the current nightly rustc as the compiler doing the work.

For platform engineers who need Rust on an obscure target today, neither project is production-ready for that goal: mrustc supports an older Rust version, and crustc is an ARM64-specific demo of a toolchain still in development. The practical path for a new obscure target is likely to contribute LLVM support for that target first, with cilly as a fallback for targets where that path is not feasible.

## Conclusion

crustc is worth examining for platform engineers who need to bring Rust to systems where LLVM and GCC are unavailable, and for compiler researchers interested in practical Rust-to-C translation. It is not ready for production use on general Rust projects: the README advises against enabling compiler optimizations during the build, notes rough edges in the generated C, and confirms that the output is architecture-specific. The full cilly toolchain, not just this demo, is what would be needed for arbitrary Rust-to-C compilation; crustc shows only that rustc itself can be compiled through that path.

## FAQ

### What is cilly and how does it relate to crustc?

cilly is the Rust-to-C compiler toolchain that generated the crustc repository. crustc is the output of running cilly on rustc itself. The full cilly toolchain can compile arbitrary Rust programs to C for any target; crustc shows only that the compiler itself can be compiled this way.

### Can crustc be used to compile Rust programs on architectures other than ARM64?

The generated C in the crustc repository targets ARM64 Linux, which is the author's workstation. The README states that cilly-generated C is compiler-specific and cannot be reused across architectures. To use crustc on a different architecture, you would need to regenerate the C using cilly for that target.

### Why does crustc require LLVM if the goal is to compile Rust without LLVM?

The Rust compiler (rustc) itself links against LLVM internally. crustc is a translation of that LLVM-linked compiler to C, so the resulting binary still requires the LLVM shared library at runtime. The cilly toolchain enables compilation of Rust programs on targets without LLVM, but the compiler doing the translation still runs on a machine that has LLVM.

## Sources

- [FractalFir/crustc on GitHub](https://github.com/FractalFir/crustc)
- [Issues](https://github.com/FractalFir/crustc/issues)
- [README](https://github.com/FractalFir/crustc/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/fractalfir-crustc
