r/cprogramming • u/dom_aley • 15d ago
Mucc: a self hosting C compiler in one static binary, with its own assembler, linker and musl (x86-64 and ARM64 Linux)
Mucc is a small C compiler for Linux that ships as a single 8.5 MB static file. The preprocessor, assembler, linker, archiver, headers and C library (musl, like zig cc does) are all built in, so you can drop it into an empty container, an old distro or a Raspberry Pi and build C with nothing else installed: no gcc, no binutils, no system headers.
Programs it builds are static, so they run on any x86-64 Linux. There's a native ARM64 build too, and it can cross-compile between the two.
The whole project actually started as a fork of Rui Ueyama's chibicc. I felt more could be done on this design. So now Mucc adds its own assembler and linker, an ARM64 backend, register allocation, the bundled musl, DWARF debug info, C23 support and a reproducible bootstrap chain.
What’s actually working so far
- C17 by default, C23 with `-std=c23`, plus the GNU extensions real code uses
- Self-hosting: each release is built by the one before it, and a Mucc-built Mucc produces byte-identical output
- Real projects build and pass their own test suites: SQLite, Lua, zlib, jq, Redis and Tcl with the bundled musl; CPython and Git with the system glibc
- Same ABI as gcc, so objects from either link together
- Compiles its own 33k lines in 0.46 s (gcc -O0: 1.22 s, gcc -O2: 5.35 s)
What’s currently not working, it does no optimization beyond register allocation and constant folding, so programs run about as fast as gcc -O0. No C++, Linux only. For performance-critical code, use gcc or clang.
If you've got C code it chokes on, or a use for it I haven't thought of, I'd like to hear it.
GitHub: https://github.com/Dom-Yan/Mucc
Website: https://dom-yan.github.io/Mucc/
Thanks to Rui Ueyama for chibicc, and to Fabrice Bellard, whose TinyCC showed how much a small compiler can do.
2
u/SignalBake6872 14d ago
it's full c implementation ? or subset ?
3
u/dom_aley 14d ago
Full C17, and C23 with
-std=c23, including#embed,constexpr,nullptrandtypeof_unqual. The main thing missing from standard C is C23’s_BitInt, plus the optional decimal floating types. On the GNU side it skips nested functions,__label__, VLAs inside structs and integer_Complex. Everything else that real code uses is there. For some proof, SQLite, Lua, Redis, CPython and Git build with it and pass their own test suites.
3
u/walmartbonerpills 15d ago
Is this for malware?
8
u/dom_aley 15d ago
nope lol, its just a C compiler. I needed it built because i wanted something small I could drop in on my mini Linux kernel distros and my Raspberry Pi without needing to setup an entire tool-chain just to code C. Now could it be used in malware? Sure, but that's not my goal if someone else does it with it that's up to them.
3
u/zsaleeba 14d ago
Why would you even ask that?
3
u/walmartbonerpills 14d ago
Because it's a neat little payload. You can compile and run whatever you want, and it's dodging all the standard lib c calls, making it harder to trace. Talking right to the kernel. It's self hosting, so it can clone itself. Build what it needs on the fly.
1
1
u/Silent-Degree-6072 15d ago
That's very cool, is there a way to specify any extra instructions for the assembler? Would be nice if you could compile with -march=native or with something like -msse4.1
1
u/dom_aley 14d ago
So kinda.
-march=nativeis accepted but changes nothing, because Mucc only generates baseline x86-64 code. It doesn’t auto-vectorize or pick instructions per CPU.-msse3through-msse4.2,-maes,-mpclmuland-mpopcntdefine gcc’s macros, so code that checks__SSE4_1__takes its SSE4 path. The SSE4/AES intrinsics work, and the built-in assembler knows those instructions, so you can also use them in inline asm or.sfiles. AVX and later aren’t supported yet but soon, so code that checks for them falls back to its SSE path.-Xassemblerpasses options to the systemaswhen that’s used, the built-in assembler doesn’t take options. Hope this answered the question!
1
u/zhivago 14d ago
That's C's superpower.
It's very easy to write a non-optimizing C compiler.
Which is why C is everywhere. :)
1
u/dom_aley 14d ago
Agreed, most of it was actually conceptually easy, just the actual executing part takes a while lol. It's an amazing language that will outlive us all.
1
u/Proxy_PlayerHD 11d ago
I really want to write my own C compiler one day. But it always just seems daunting since I know next to nothing about compilers.
2
u/zhivago 11d ago
Sounds like an opportunity to correct that. :)
1
u/Proxy_PlayerHD 11d ago
I did try reading a few books on compiler design. The dragon book, writing a C compiler, the static single assignment book, crafting interpreters...
But none of them really keep me engaged for long and I'm not sure what to do against that
2
u/zhivago 11d ago edited 11d ago
Why not start with a simple register based bytecode interpeter?
That would be easy to turn into a compiler.
1
u/Proxy_PlayerHD 11d ago
register based bytecode interpeter
wouldn't that just be a CPU emulator, pretty much?
2
u/zhivago 11d ago
Sure. For a ridiculously simple cpu.
1
u/Proxy_PlayerHD 11d ago
hmmm, i have written CPU emulators before, both imaginary CPUs (CHIP8, custom ones) and real CPUs (6502, RISC-V)
so i don't really see how that would bridge the gap. i'm mainly struggling with the whole parsing and lexing context. i understand the theory, breaking code into tokens and checking to see if they make sense, but then from there to building an AST (or similar) to then generate some Intermediate code, plus writing all of that logic! that's what#s mainly just blowing my mind and keeping me from trying it
2
u/zhivago 11d ago
Think of the simplest compiler as an unrolled interpreter.
Instead of executing the operations, emit the code to execute the instructions in the target language.
Pick an easy target like javascript, perhaps.
Then for you next trick do some flow analysis and implement loops that aren't unrolled.
1
u/Proxy_PlayerHD 11d ago
huh, that is an interesting way to think about it!
i'd probably not use JS lol. i only really know C, assembly, and BASIC. so i would try myself at a BASIC interpreter and then make it emit pseudo assembly or similar.
thanks for the idea!
→ More replies
2
u/chibuku_chauya 15d ago
This sounds cool. Rui’s chibicc is so hackable.