kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

kit

Kit is a BusyBox for compilation: one multi-call executable and one C library covering the compiler, linker, binary utilities, execution runtimes, package distribution, and builds.

A conventional toolchain is assembled from several layers. cc coordinates preprocessing, compilation, assembly, and linking; binutils handles archives and object inspection; JIT and WebAssembly runtimes are separate again; build and package systems sit above and after them. Kit gives those layers a shared target registry, object model, linker, content store, and public API.

Kit is implemented in freestanding C11. It does not require a C++ compiler to bootstrap, has no mutable global state, and makes host services explicit through context structs and vtables. The kit executable is the reference host for libkit.a, not a separate implementation wrapped around it.

For a longer introduction, including representative compile-speed and code-size comparisons, see Introducing kit.

Quick start

From a source checkout:

make bin
K=build/kit

From an extracted release:

K=bin/kit

Compile, inspect, and run a native program:

printf 'int main(void) { return 0; }\n' > hello.c
"$K" cc hello.c -o hello
"$K" objdump -h -t hello
./hello

"$K" run hello.c
"$K" run --no-jit hello.c

Native distributions discover their sibling support tree automatically. Native macOS builds also discover and apply the SDK. An explicit --support-dir, --sysroot, or -isysroot remains an authoritative override.

Inspect the compiled target profiles before cross-compiling:

"$K" targets
"$K" targets aarch64-linux-gnu
"$K" cc -target aarch64-linux-gnu --sysroot /path/to/sysroot \
  -c hello.c -o hello.aarch64.o

Hosted cross targets currently require an appropriate SDK or sysroot. Freestanding targets use kit's shipped runtime sources and caller-supplied startup/linker policy. Signed .kpkg SDK distribution is planned; see the sysroot plan.

Install the multi-call binary under conventional tool names:

mkdir -p "$HOME/.local/bin"
"$K" install "$HOME/.local/bin"

Kit creates symlinks on POSIX and hard links on Windows. kit cc ... and an installed cc ... invoke the same command implementation.

What is included

Surface Commands and APIs
Compilation C11 preprocessor/compiler, assembly, cc, check, cpp, as, ld, build-exe, build-lib, build-obj
Binary tools ar, ranlib, nm, size, strip, objcopy, objdump, addr2line, symbolize, strings, disas, mc, image, cpio
Execution Native JIT with run, IR interpreter with run --no-jit, interactive dbg, Wasm/WAT execution with explicit host-resource policy
Targets AArch64, x86-64, RISC-V, Arm freestanding, and wasm32 across ELF, Mach-O, COFF/PE, and Wasm profiles
Distribution Content-addressed cas, signed .kpkg/portable packages with pkg, managed release installation and rollback with update
Builds Content-addressed build targets, tests, configuration profiles, declared recipe inputs, dependency traces, external repositories, and output trees
Data tools SHA-256, BLAKE2b-256, CRC-32, gzip, LZ4 frame, xxd, and cmp, including conventional command aliases
Generation gram EBNF-to-C parser/lexer generation with allocation-free push runtimes
Library Public C APIs for compilation, code generation, objects, linking, JIT, debugging, DWARF, archives, hashing, compression, CAS, packages, builds, and targets

Run kit --help for the compiled tool inventory and kit help COMMAND for the authoritative command-line reference.

Packages and trust

Kit separates content identity from trust. Blobs and canonical directory trees are addressed by BLAKE2b-256 and can come from an untrusted store. A canonical package manifest names output trees and artifact roles; a Minisign-compatible Ed25519 signature authorizes that claim.

kit pkg keygen -o release-key
kit pkg create --name app --version 1 -s release-key.key \
  --root out -o app.kpkg
kit pkg verify -p release-key.pub app.kpkg
kit pkg unpack --verify -p release-key.pub app.kpkg -C installed

The native .kpkg representation may be fat, metadata-rich, or thin. A portable .tar.gz representation carries the same signed logical package. Kit uses this machinery for its own releases and authenticates both the release channel and selected package before kit update changes the active toolchain.

See Code distribution and Releasing and updating kit.

Build system

kit build is a build system, not an alias for cc. A package-local BUILD.kit maps target labels to recipe executables. Recipes receive a clean environment, write an output directory, and declare configuration, source, glob, fetch, and target dependencies through the recipe protocol.

kit-build 1
[target app]
recipe recipes/app.sh
kit build //:app

Outputs are canonical content-addressed trees. Deep traces handle unchanged transitive inputs; shallow traces can reuse a parent when a changed dependency rebuilds to the same output. The current contract relies on recipes declaring all cache-visible inputs; filesystem hermeticity enforcement and build-store garbage collection remain future work.

See Content-addressed build coordinator.

Optimization and scope

-O0 emits through the direct native backend. -O1 records IR and runs the fast, non-SSA optimization and register-allocation pipeline. -O2 is currently accepted as an alias for -O1; the distinct SSA mid-end is maintained but not yet enabled as a public optimization level.

Kit is not intended to hide its current boundaries:

Embedding and bootstrapping

An embedder owns the host callbacks and the lifetime of its KitContext, target, compiler, compile/object/link sessions, and writers. The public headers are the API contract; the driver and most frontends are built against the same boundary without access to internal headers.

See Embedding libkit, Design, and Interfaces.

Kit's normal self-host check starts from a host C compiler, builds kit, and then uses kit for two more stages. Stage 2 and stage 3 must be byte-identical. Because the implementation is C, replacing the initial compiler with a smaller seed does not require first constructing a C++ toolchain; a minimal/diverse seed is a separate trust project, not a claim of the current build.

See Build and configuration.

Documentation

Start with the documentation map. Common routes are:

Task Documentation
Learn the architecture DESIGN.md
Use and extend the CLI DRIVER.md
Inspect targets and portability lanes PORT.md
Embed the library EMBEDDING.md, INTERFACES.md
Package and authenticate artifacts DISTRIBUTE.md
Define builds BUILD_COORDINATOR.md
Work on kit itself BUILD.md, TESTING.md
Measure performance and size BENCHMARKING.md, CODE_SIZE.md

Durable doc/*.md files describe implemented behavior. Forward-looking work is under doc/plan; speculative designs are under doc/ideas.

Building and testing

make lib     # libkit.a
make bin     # kit
make rt      # libkit_rt.a

Prefer the targeted suites listed in TESTING.md. Portability and self-host testing are separately provisioned and documented in PORT.md.