kit

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

commit ed7f379593b1990849bff38040e04435222cb9b0
parent 30edea9e33151f5d7fc5ba2c19f3b7111b6ab797
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Thu, 18 Jun 2026 12:24:35 -0700

doc: plan kitc support library

Diffstat:
Adoc/plan/KITC.md | 295+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdoc/plan/README.md | 1+
2 files changed, 296 insertions(+), 0 deletions(-)

diff --git a/doc/plan/KITC.md b/doc/plan/KITC.md @@ -0,0 +1,295 @@ +# kitc support library + +This document sketches a future `kitc` library: a Kit-provided C utility +library that is distributed with the toolchain, built on demand for the active +target, and linkable from both file-output builds and JIT runs. + +`kitc` is deliberately **not** libc and not the compiler runtime. It is an +ordinary opt-in support library for data structures, algorithms, encoding, +small platform abstractions, and other reusable C utilities that are useful to +programs compiled by Kit. + +## Goals + +- Ship reusable C utility APIs under a Kit-owned namespace. +- Make the library available to C programs, C "scripts" run through `kit run`, + and cross-compiled targets. +- Build archives on demand from source, using Kit itself, instead of shipping a + prebuilt archive for every target and ABI variant. +- Use the normal linker and archive semantics once the archive exists: no + special symbol resolution path, no JIT-only library path. +- Keep freestanding code usable without libc or host syscalls. +- Distribute the source tree through the existing signed package/CAS machinery + once package-based support assets are user-facing. + +## Non-goals + +- `kitc` is not a C standard library implementation. +- `kitc` must not define standard libc symbols such as `printf`, `malloc`, or + `memcpy`. +- `kitc` must not be required for ordinary C code generation. Compiler helper + routines remain in `libkit_rt.a`. +- `kitc` must not introduce hidden global state. Stateful APIs take explicit + context structs or caller-owned storage. +- The initial implementation does not need a new public libkit API. Driver-side + support is enough until embeddings need the same facility. + +## Relationship to existing support libraries + +`libkit_rt.a` is part of the compiler substrate: integer/floating helpers, +atomics, setjmp/coroutines, freestanding header support, and other pieces that +compiled code may need even when the user did not ask for a utility library. +The driver already resolves a target runtime variant, builds the archive on +demand, caches it under `build/rt` or the user cache, and inserts it into the +link at the policy point required by the target. + +`kitc` should reuse that shape, but with different policy: + +- headers are under `<kitc/...>`, not the freestanding libc header namespace; +- symbols are prefixed with `kitc_`; +- linking is explicit, normally via `-lkitc` or a driver sugar flag; +- archive insertion is lazy and ordinary, just like any other static library; +- hosted/OS-dependent helpers live in a separate component from freestanding + core utilities. + +By the time a link session sees `kitc`, it should be just another archive input. +All special behavior belongs before linking: locating the source package, +choosing the target variant, compiling the source set, caching the archive, and +inserting the archive in the requested link order. + +## Source layout + +The library should live outside `rt/`: + +```text +kitc/ + include/ + kitc/ + base.h + vec.h + str.h + ... + src/ + vec.c + str.c + ... + manifest.kitc + LICENSE +``` + +The manifest is the source of truth for the driver-side builder. It should +record the library version, components, source files, public include roots, and +target/feature gates. It should be canonical text so it can be hashed directly +or stored as a CAS blob later. + +Possible component split: + +| Component | Scope | +|-----------|-------| +| `kitc-core` | Freestanding utilities: containers, string slices, hashing adapters, encoders, parsers, formatting into caller-provided buffers, no syscalls. | +| `kitc-hosted` | File, environment, time, process, terminal, and other helpers that require hosted OS/libc facilities. | +| `kitc-extra` | Optional heavier modules that should not be pulled in by the default utility library. | + +The default `-lkitc` spelling should start with `kitc-core`. Hosted helpers can +be exposed as `-lkitc_hosted` or a later explicit feature flag. + +## Command-line surface + +The primary interface should be ordinary library spelling: + +```sh +kit cc app.c -lkitc +kit run script.c -lkitc +kit cc -target aarch64-linux app.c -lkitc +``` + +A convenience flag such as `--kitc` can be added later, but it should lower to +"add the kitc include root and lazy-link the selected kitc archive". The driver +should not auto-link merely because a source included `<kitc/foo.h>`: include +resolution and link input selection should stay separate. + +Header search policy can be friendlier than link policy. It is reasonable for +the driver to add the `kitc/include` root to the system include set when Kit +support headers are enabled, so a source can write: + +```c +#include <kitc/vec.h> +``` + +But a reference to `kitc_vec_*` still requires an explicit library input. + +## On-demand build and cache identity + +The first implementation can mirror `driver/lib/runtime.c`: + +1. Resolve the active `KitTargetSpec`. +2. Select the `kitc` variant/component from `manifest.kitc`. +3. Build each source file with a `KitCompiler` configured for the target. +4. Archive the resulting object builders or object bytes with `kit_ar_write`. +5. Insert the archive path as a normal lazy archive input. + +The cache key should be content-based rather than only mtime-based: + +```text +kitc source tree id ++ manifest version ++ component name ++ target triple / target key ++ object format and OS ++ ABI/data-model axes: pointer size, alignment, float ABI, long double, int128 ++ -march / -mabi or equivalent target ISA options ++ codegen-affecting feature flags ++ debug/profile/sanitizer variant when those are supported +``` + +Recommended cache locations: + +```text +<checkout>/build/kitc/<target-key>/<config-id>/libkitc.a +$KIT_HOME/cache/kitc/<target-key>/<config-id>/libkitc.a +``` + +In a checkout or explicit support directory, prefer the in-tree cache so local +development shares artifacts with `make` targets. In an installed distribution, +prefer the user cache so the tool never writes into the install tree. + +Staleness should eventually be determined by the source tree id and config id. +An initial mtime fallback is acceptable if the tree-id plumbing is not ready, +but the design target is reproducible content identity. + +## Distribution + +`kitc` should be distributed as source, not as prebuilt target archives. + +Prebuilt archives multiply across architecture, OS, object format, ABI, ISA +options, and feature flags. Source distribution keeps the package small and +matches Kit's self-hosting story: any target Kit can compile can get a matching +`kitc` archive on demand. + +Long-term distribution should use the existing signed package and CAS layers: + +1. Release packaging stores the `kitc` source tree as a CAS tree. +2. A signed `.kpkg` claims the tree id, version, and metadata. +3. Install or first use materializes the tree under the Kit support root, or + reads it from the local CAS when direct tree reads are available. +4. The on-demand builder keys compiled archives by that source tree id plus the + target/config id. + +This gives `kitc` the same verification story as other support assets without +requiring a new distribution format. + +## JIT and C scripts + +The JIT path should need no special linker support. For: + +```sh +kit run script.c -lkitc +``` + +the driver should: + +1. Compile `script.c` to an object builder for the host-compatible target. +2. Ensure the selected `libkitc.a` exists for that same target. +3. Add `libkitc.a` as a lazy archive input after user objects. +4. Add `libkit_rt.a` according to the existing runtime policy. +5. Open a link session with `KIT_LINK_OUTPUT_JIT`. +6. Call `kit_link_session_jit`. + +Because the JIT uses the same object, archive, relocation, and symbol-resolution +machinery as file output, archive member selection should behave identically. +If `kitc-hosted` calls host libc functions, those are resolved through the +existing JIT extern resolver and call-stub/GOT machinery. `kitc-core` should not +depend on that path. + +## Driver integration + +The first cut can stay driver-local: + +```text +driver/lib/kitc.c +driver/lib/kitc.h +kitc/manifest.kitc +kitc/include/... +kitc/src/... +``` + +Proposed driver helper responsibilities: + +- locate the `kitc` source/support root; +- parse or load the source manifest; +- select a component and target variant; +- compute or approximate the archive cache key; +- build missing/stale archives; +- return a `DriverArchiveInput` compatible with the existing link input set. + +`cc`, `ld`, and `run` should not grow independent `kitc` logic. They should call +the shared helper when `-lkitc` or a future sugar flag requires it, then insert +the returned archive through the same `DriverLinkInputSet` path used for other +archives. + +If embeddings later need this feature, promote the concept into a public support +library API. Until then, keeping it in the driver avoids freezing a broad API +too early. + +## Link ordering + +For normal links, `libkitc.a` should appear where the user requested `-lkitc`. +That preserves ordinary archive behavior and lets users control dependency +order. + +For a future `--kitc` sugar flag, insert the archive after user source/object +inputs and before the compiler runtime. This order lets user code pull needed +`kitc` members lazily, and lets both user code and `kitc` pull compiler-runtime +helpers as needed. + +Windows runtime special cases should remain owned by the runtime insertion code. +`kitc` should not duplicate runtime archive placement rules. + +## Open questions + +- Manifest format: use a small canonical custom text format, or reuse a broader + package/build manifest format once that stabilizes? +- Header availability: should `<kitc/...>` be on by default for `cc` and `run`, + or only enabled when `-lkitc`/`--kitc` is present? +- Hosted split: should hosted helpers be a separate archive from day one, or a + component selected from one manifest? +- Build coordinator integration: should `kitc` archive builds eventually be + modeled as content-addressed build targets, so remote trace reuse can avoid + rebuilding popular variants? +- Version policy: is `kitc` versioned exactly with Kit releases, or can package + channels ship newer `kitc` source trees to older compatible Kit binaries? + +## Phased implementation + +### Phase 1: local source archive + +- Add the `kitc/` tree with a small freestanding `kitc-core` surface. +- Add a driver-local builder modeled on runtime archive generation. +- Recognize `-lkitc` and replace it with an ensured archive path. +- Add targeted tests for `kit cc app.c -lkitc` and `kit run app.c -lkitc` on + the native target. + +### Phase 2: target matrix + +- Extend the variant table/manifest across the release support set. +- Add cross-target archive build tests for a small source corpus. +- Validate freestanding targets do not accidentally depend on hosted libc + symbols. + +### Phase 3: content identity + +- Compute a source tree id and config id for archive caches. +- Stop relying on mtimes when content identity is available. +- Share cache layout with the support/install root policy. + +### Phase 4: signed package distribution + +- Package the `kitc` source tree as a signed `.kpkg`. +- Materialize it under the support root during install or first use. +- Key archive builds by the package tree id. + +### Phase 5: broader library surface + +- Add hosted and optional components behind explicit link spellings. +- Consider public support-library APIs only after the driver-local shape has + real users and stable requirements. diff --git a/doc/plan/README.md b/doc/plan/README.md @@ -18,6 +18,7 @@ shrinks to whatever remains open (and is deleted once nothing remains open). | [ARM32.md](ARM32.md) | 32-bit ARM (`arm-none-eabi`, ARMv7-M/ARMv7E-M Thumb-2, Cortex-M3/M4/M7) freestanding backend: Phase 1 (walking skeleton) is landed; Phase 2 tracks the remaining ops, the -O1 known-frame path, 64-bit, atomics, TLS, and the `qemu-system-arm` cross-test lane. | [../ARCH.md](../ARCH.md), [../PORT.md](../PORT.md) | | [MCU.md](MCU.md) | Microcontroller development workflow for STM32 Cortex-M (ARMv7-M/E-M) and Espressif RISC-V (ESP32-C/H/P): the last-mile gaps over the working backends — `objcopy` ihex/srec, reusable startup/vector-table + starter linker script, the rv32 soft-float-default footgun, SDK interop, and on-target debug. Assessment stage; references ARM32.md for ARM-core follow-ons. ARMv6-M/Cortex-M0 and Xtensa are out of scope. | [ARM32.md](ARM32.md), [../RUNTIME.md](../RUNTIME.md), [LINKER.md](LINKER.md) | | [SYSROOTS.md](SYSROOTS.md) | Cross-compile sysroot packaging: minimal per-target stubs/headers/CRT objects distributed via `.kpkg` for the support set. Design complete, implementation not yet started. | — | +| [KITC.md](KITC.md) | The planned `kitc` utility library: source distribution, on-demand target archive builds, driver integration, and JIT/script linking. | [../RUNTIME.md](../RUNTIME.md), [../LINK.md](../LINK.md), [../JIT.md](../JIT.md) | | [TODO.md](TODO.md) | Open deferred fixes and code smells, plus terse backlog folded from retired plan docs (arch-backend parity, Wasm object backend, Windows x64 self-host, bootstrap breadth). Completed items are removed instead of checked off. A current backlog, not a roadmap. | — | Speculative, not-committed designs (no code, parked) live in [`../ideas/`](../ideas/)