Chibil: A C Compiler Targeting .NET IL
#Dev

Chibil: A C Compiler Targeting .NET IL

AI & ML Reporter
4 min read

Michal Strehovsky’s Chibil rewrites the tiny chibicc compiler in C# to emit COFF objects that run on the .NET runtime, enabling C code—including a Doom port—to be built and debugged alongside C++/CLI, but it still lacks a full C standard library and a cross‑platform linker.

Chibil: A C Compiler Targeting .NET IL

Featured image

What’s claimed – The repository advertises Chibil as a complete C compiler that takes ordinary C source, emits COFF object files compatible with Microsoft’s link.exe, and produces executables that run on the .NET Common Language Runtime (CLR). The author demonstrates that the compiler is “complete enough” to compile the classic Doom source (PureDOOM) and that the generated binaries can be debugged with standard .NET debuggers.

What’s actually new – The novelty lies in three tightly coupled pieces:

  1. Port of chibicc to C# – The original chibicc is a pedagogical C compiler written in a few hundred lines of C. Strehovsky rewrote the front‑end and code‑gen stages in C#, preserving the same minimalist design while targeting the .NET Intermediate Language (IL) instead of native machine code.
  2. COFF‑OBJ output for the CLR – The compiler emits Windows COFF object files that contain IL bytecode and the necessary CLR metadata. Because the objects follow the same format as those produced by MSVC in /clr mode, they can be linked with C++/CLI code using the stock Visual Studio linker (link.exe). This makes it possible to mix hand‑written C# or C++/CLI with C compiled by Chibil without any custom toolchain.
  3. Debug‑friendly metadata – Line numbers and local variable information are preserved in the generated IL, so a developer can step through the original C source in Visual Studio, Rider, or any other .NET debugger. This is a rare feature for a C‑to‑IL pipeline.

The repository also ships a small runtime stub (crt/) that adapts the .NET string[] args entry point to the traditional int main(int argc, char **argv) signature, and a helper (asm2obj) that converts raw IL assembly into a COFF object.

Limitations and open problems

Area Current state Practical impact
Standard library Only a minimal stub is provided; no full libc implementation. Porting existing C projects that rely on stdio.h, stdlib.h, etc., requires either rewriting those parts in C# or manually providing P/Invoke wrappers.
Linker Relies on Microsoft link.exe; no native cross‑platform linker yet. Building on Linux or macOS is not possible without a Windows environment or a Wine setup. The author mentions a future self‑contained linker to address this.
Interop Generated code lives in the global namespace; consuming it from other .NET assemblies requires reflection (Module.GetMethod). Automatic exposure of C functions as .NET methods (e.g., via [DllExport]‑style attributes) is missing, making library‑style use cumbersome.
Tooling Only a COFF object dumper (coffobjdumper.cs) is provided for inspection. No IDE integration for incremental builds, no support for Visual Studio project files, and no source‑level diagnostics beyond what chibicc already offers.
Platform support Windows‑only due to COFF and link.exe. Limits the appeal for developers targeting Linux/macOS containers or cross‑compiling to ARM.

Why it matters

  • Educational value – By re‑implementing a tiny C compiler in a managed language, the project offers a clear case study of how high‑level language front‑ends can target a virtual machine rather than native code. Readers can inspect the source to see how abstract syntax trees are lowered to IL instructions.
  • Mixed‑language scenarios – Teams that already have a substantial C++/CLI codebase can now add pure C modules without pulling in a separate native toolchain. The IL objects behave like any other .NET assembly, which simplifies deployment (single‑file EXE or self‑contained DLL).
  • Debugging experience – Stepping through C code in a .NET debugger is unusual. It can help developers understand how their C logic maps to IL, which is useful for performance tuning or for teaching compiler construction.

What to watch next

  • A self‑contained linker would remove the Windows dependency and open the door to cross‑platform builds. If the author implements a lightweight COFF linker in C#, the entire pipeline could run on any platform that supports .NET 8+.
  • Adding a more complete C runtime (perhaps by wrapping parts of libc via P/Invoke or by porting a small subset of musl) would make Chibil viable for larger open‑source projects.
  • Interop helpers that automatically generate .NET wrappers for exported C functions would lower the barrier for using Chibil as a library compiler rather than just an executable builder.

Bottom line – Chibil is not a drop‑in replacement for GCC or clang, but it does provide a functional, source‑level C‑to‑IL compiler that can produce runnable .NET binaries and interoperate with existing C++/CLI code. Its current constraints keep it in the niche of experiments and teaching, yet the approach demonstrates that the CLR can serve as a viable backend for languages that historically target native code.

Repository: https://github.com/MichalStrehovsky/chibil

Comments

Loading comments...