kit

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

Embedding libkit

Kit ships as both the kit multi-call executable and lib/libkit.a. The driver is the reference host for the library: it uses the public headers under include/kit/ and supplies the OS-facing callbacks that freestanding libkit does not provide itself.

This document is the entry point for an application embedding compilation, objects, linking, JIT, debugging, packages, or builds. Exact signatures and ownership annotations live in the public headers; the architectural boundary inventory is in INTERFACES.md.

Link against the distribution

For an extracted native distribution:

ROOT=/path/to/kit
K="$ROOT/bin/kit"

"$K" cc -I "$ROOT/include" embed.c "$ROOT/lib/libkit.a" -o embed
./embed

Native support and SDK discovery follow the same rules as kit cc. An explicit --support-dir, --sysroot, or -isysroot overrides discovery. The static library has no extra user-selected dependency when linked through the native hosted profile.

Include the narrow headers for the APIs in use; there is intentionally no whole-library kit.h umbrella. Common entry points are:

Task Header
Context, compiler, writers, diagnostics <kit/core.h>
Target profiles and triples <kit/target.h>
High-level source compilation <kit/compile.h>
Language/frontend code generation <kit/frontend.h>, <kit/cg.h>
Objects and archives <kit/object.h>, <kit/archive.h>
Linking and JIT publication <kit/link.h>, <kit/jit.h>
Debug information and debugger sessions <kit/dwarf.h>, <kit/dbg.h>
Content store and packages <kit/cas.h>, <kit/package.h>
Content-addressed builds <kit/build_coord.h>

Host contract

Libkit is freestanding and owns no process-global host adapter. The embedder constructs a KitContext and keeps its referenced callbacks alive for every object that uses them.

The common context may provide:

The heap callbacks must honor the requested alignment. Input slices are usually borrowed for the duration stated by the API; a context callback's user data must outlive every operation that can call it.

JIT and debugger operations require additional, deliberately separate host interfaces:

Keeping these interfaces separate means an embedder that only compiles or links does not need to provide executable-memory or signal machinery.

Common lifecycle

  1. Initialize the embedder-owned KitHeap, KitDiagSink, optional KitFileIO, and KitContext.
  2. Parse a target with kit_target_from_triple, or select a public target profile from <kit/target.h>.
  3. Create a KitTarget with kit_target_new.
  4. Create a KitCompiler with kit_compiler_new or kit_compiler_new_ex.
  5. Create short-lived compile, object, link, JIT, debug, package, or build sessions under that compiler/context.
  6. Free sessions and builders before freeing the compiler; free the target after the compiler.

No mutable process-global compiler exists. Independent contexts and compiler handles may coexist, subject to the thread-safety rules documented by each specific public API.

Compile and link lifecycle

The high-level source path is defined by <kit/compile.h>:

  1. Fill KitCompileSessionOptions, including the registered language and frontend input kind.
  2. Create a KitCompileSession with kit_compile_session_new.
  3. Stage a caller-owned KitSourceInput with kit_compile_session_stage. Source names and bytes must remain valid for the duration documented by the header.
  4. Consume the returned KitObjBuilder: emit it, inspect it, or add it to a link session.
  5. Publish the final output through a caller-owned KitWriter.
  6. Call kit_compile_session_commit only after publication succeeds. On every abandoned or failed staged path, call kit_compile_session_abort.

For a file image, create a KitLinkSession from <kit/link.h>, add object builders or borrowed object/archive/DSO bytes in command-line order, resolve, and emit through a KitWriter. The linker owns resolution and layout policy; the caller owns its input buffers and output sink unless a specific API says otherwise.

Cleanup is the reverse of construction:

writer -> link session -> object builder -> compile session
       -> compiler -> target -> embedder-owned context services

Language frontends

A language can bypass the high-level compile session and emit directly through KitCg from <kit/cg.h>. Frontends should include <kit/frontend.h>, the tier-scoped front door that re-exports the code-generation, compile, source, and arena facilities intended for frontend authors.

The frontend provides a KitFrontendVTable, registers it with the compiler, and emits semantic operations into a KitObjBuilder. It does not own target object formats, ABI layout policy, or linking. Those remain behind the public codegen/object/link boundaries.

The C, cpp, and internal Toy frontends are built without access to src/ headers and are useful boundary examples. The Wasm frontend has one documented internal-module exception; external frontends should not copy that exception.

See FRONTENDS.md and CODEGEN.md.

Object, JIT, and distribution paths

The public API is intentionally composable:

The command-line tools are thin hosted examples of these compositions. They are not additional privileged entry points into libkit internals.

Error handling and ownership checklist