Slimcc
C23 compiler with C2y/GNU extensions for x86-64 Linux/BSD, written in C99
Install / Use
/learn @fuhsnn/SlimccREADME
This is a fork of Rui Ueyama's chibicc with fixes and enhancements, including:
- C99 features: VLA parameters, VLA de-allocation, K&R old-style functions.
- C11 features:
_Static_assert(), over-aligned locals,_Genericwith qualifiers. - C23 features:
constexpr,enum:T,#embed,auto,_BitInt,nullptr,={} - C2Y features: named loops,
ifdeclarations,_Countof. defer/_Defer: enable un-uglified form with-fdefer-tsoption or#include <stddefer.h>.- WG14 proposals:
__VA_TAIL__,#def #enddef. - GNU features: inline assembly, commonly used
__attribute__'s. - MSVC features:
#pragma pack, anonymous struct. - Basic codegen optimizations (close to GCC/Clang at
-O0).
What can it build?
Compiling real C projects with slimcc has been a major focus, the CI workflow now regularly build-test a healthy collection of familiar names, for bragging rights:
- Core system commands (GNU utils, busybox, toybox, bash, zsh)
- Command-line tools (curl, git, jq, wget, rsync, apk, pacman)
- Programming languages (Python, Go, Lua, Perl, Ruby, PHP, Ocaml, Erlang, C3, Zig)
- Gamedev/graphics libraries (SDL3, glfw, stb, raylib, sokol)
- Critical infrastructure software (Redis, Valkey, Nginx, PostgreSQL)
slimcc-musl-bootstrap is a minimal statically-linked chroot environment with musl, binutils, toybox entirely compiled with slimcc.
Building and Using
- Recent GNU binutils is required.
- Find a relevant preset in
platform/, copy/symlink toplatform.cor create one, hitmake. - On recent glibc Linux, this should just work:
ln -s platform/linux-glibc-generic.c platform.c
make
- For simplicity, built-in headers are searched relative to the binary, it's intended to be executed in-tree like:
~/slimcc/slimcc *.c
CC=~/slimcc/slimcc ./configure
cmake -DCMAKE_C_COMPILER=/home/username/slimcc/slimcc
- For installing/symlinking/packaging, please edit
platform.cwith absolute paths. cc scripts/amalgamation.cbuilds the project as a single translation unit.make slimcc-asan/test-asanbuild and run tests with address sanitizer, recommended if you are hacking the source.make slimcc-filc/test-filcbuild and run tests with Fil-C, envFILCis used.
Compatibility
- Autoconf based projects might fail to build due to
-fPICor-Wlnot being passed. If there is a block in./configurethat looks like below, append-Wl,,-fPIC,-staticrespectively and re-configure:
lt_prog_compiler_wl=
lt_prog_compiler_pic=
lt_prog_compiler_static=
- CMake: these extra flags might be helpful:
-
-DCMAKE_PREFIX_PATH: helpfind_package()find installed libraries.
-
-DCMAKE_C_COMPILE_OPTIONS_PIC=-fPIC
-
-DCMAKE_C_COMPILE_OPTIONS_PIE=-fPIE
- Meson: see https://github.com/mesonbuild/meson/issues/5406. Try Muon.
- Muon: slimcc works ok under Muon's posix cc mode, for better compatibility, register slimcc in Muon's
src/script/runtime/toolchains.mesonwith:
toolchain.register_compiler(
'slimcc',
inherit: 'posix',
linker: 'ld',
detect: func(out str) -> int
return 'slimcc' in out ? 100 : 0
endfunc,
handlers: {
'print_search_dirs': ['-print-search-dirs'],
},
)
- Projects with deep GCC assumptions might actually work if you carefully opt in/out of
#if __GNUC__blocks, see the CI test scripts for a taste of hacks that can be done.
Compatibility options
-fms-anon-struct: Enable declaring anonymous struct member with tags like GCC's-fms-extensionsor-fplan9-extensions.-fdisable-visibility: Some projects adopt an idiom that globally set-fvisibility=hiddenthen selectively export public API with__attribute__((visibility("default"))). slimcc support both, yet a problem arises when the former is probed by build system while the latter hardcoded in#if __GNUC__blocks regardless of the build system's decision. The option simply disable both features to prevent the conflict.-ffake-always-inline: slimcc currently don't inline functions, but some projects' usage of GCCalways_inlineon non-static inline functions would cause missing definition at link time. This option turns these definitions intostatic inline's to work around compile error.
How optimized is the compiler?
The coding style is highly influenced by chibicc, which means in the eyes of C veterans there might be all kinds of inefficiencies in the name of readability. While micro-optimizing is fun, I only commit changes that noticeably improve fully-optimized builds.
As such, optimization flags and custom allocators have great impact on its performance, make slimcc-(lto/lto-mi/lto-je) is provided for optimized builds. It's usually faster than Clang/GCC for common tasks, but only by doing less internally.
How portable is the compiler?
- It's written in C99 with several POSIX 2008 functions.
- Host is assumed to be little-endian.
- For compilers with more restricted feature set, preprocessor flags are provided to enable bootstrapping stage1 with unneeded features crippled, please don't use them outside of self-hosting.
-
BOOTSTRAP_NO_LDOUBLEaliaseslong doubletodouble.
-
BOOTSTRAP_NO_VLAmakes VLA-using functions no-op (only_BitIntevaluation affected).
- As proof of portability and reproducibility, the following compilers are known to bootstrap identical stage2 of
slimcc: -
chibiccwith backported patches,widcc
-
pccwith-std=c99
-
antccwith-DBOOTSTRAP_NO_VLA
-
cprocwith-DBOOTSTRAP_NO_LDOUBLE -U__has_builtin
-
cparserwith-DBOOTSTRAP_NO_LDOUBLE
-
compcertwith-DBOOTSTRAP_NO_LDOUBLE -DBOOTSTRAP_NO_VLA -U__has_builtin -fstruct-passing
-
dmdwith-P=-DBOOTSTRAP_NO_VLA -P=-U__has_builtin, without-O, after patching out file scope compound literals withperl -i -pe 's|^([\w ]+) \*(\S+) = &\(\S+\)({.*};)$|\1 _\2 = \3\n\1 *\2 = &_\2;|g' *.c
-
- If using
platform/linux-glibc-generic.c, remember to pass-fno-pie -no-piewhen building stage2 to avoid host deterministic behavior.
- If using
-
- In case you're wondering — no, "Claude's C compiler" doesn't work, worse still, the cli option that could help bypass the miscompilation also wasn't implemented properly.
