badc can doCI builds every C translation unit of a Linux 7.2.9 defconfig kernel with
badc, on x86_64 and aarch64: 2942 and 4283 units for the kernel image. badc
also links the kernel, and both kernels boot. Each boot is checked by markers
and by self-checks of procfs and sysfs inside the booted kernel. All
defconfig modules build and load, with the same per-module results as a
gcc-built kernel.
The kernel also builds as .deb and .rpm packages from the Ubuntu 26.04
and Fedora 44 kernel configurations. The packages install into stock Debian 13,
Ubuntu 26.04 and Fedora 44 images and boot to systemd multi-user with modules
loading on demand; /proc/version names badc. At the 7.1.10 pin, the four
packages ({rpm, deb} x {x86_64, aarch64}) took 101929 C units, 467
assembly units and 59424 links, all of them badc’s: nothing fell back to
another compiler, assembler or linker.
badc -c foo.S -o foo.o assembles, and the kernel build uses it for every
assembly unit, the real-mode boot code included. Under -m16 and -m32 the
object is ELFCLASS32 / EM_386. badc makes every link, including the 32-bit
i386 ones (boot setup, the real-mode blob, the 32-bit vDSO), and writes the
dynamic metadata and symbol versions of all three vDSOs.
The kernel page has the details.
badc writes Mach-O, ELF and PE32+ directly:
| system | architectures | images |
|---|---|---|
| macOS | ARM64 | executables, dynamic libraries |
| Linux | ARM64, x86-64 | executables, shared libraries |
| Windows | ARM64, x86-64 | console, GUI, NT native and driver images, DLLs |
It also writes EFI applications and drivers. --freestanding links without
the startup runtime. x86-64 code assumes x86-64-v3, and ARM64 code the Apple
M1’s ARMv8.4-A (baseline).
The headers and the C runtime are built into the binary; --install writes
them to disk for editing. badc needs no ld, lld or link.exe, and its
linker can stand in for LD= in an existing build. It assembles .s and .S
files and inline asm.
Every build goes through SSA and a graph-coloring register allocator, and
-O adds the SSA optimization passes. The code -O produces runs faster
than clang -O0’s. CI measures badc against tcc, ccc, clang and gcc on Linux
and against MSVC on Windows for every pull request and every push to
master; the results are at
badc.dev/performance.
-g writes DWARF version 4 for lldb, gdb, rr and profilers, so breakpoints,
watchpoints and structure layouts work. On Windows targets the DWARF is in
the PE image; badc writes no PDB. The -g<level>, -ggdb, -gdwarf and
-gdwarf-<n> spellings are accepted. A request badc cannot meet, such as
DWARF 5 or -gdwarf64, reports B7011 dwarf-output, and the compile
continues with DWARF 4.
--jit compiles in memory and calls main. --interp runs the SSA IR in an
interpreter that keeps code apart from data and can check every heap access
(--interp and --jit). A .c file that starts with a
#! line can be run directly.
cargo add badc compiles and runs C from a Rust program, with std or with
alloc alone (library and no_std).