# G-005 Zig-based build infrastructure for binary dependencies from source Status: proposed Scope: src/runtime/, build.zig / build.zig.zon (new), src/make.tcl integration Goal: a zig-based build system retrieves and builds binary dependencies (including Tcl9) from source, replacing the committed-binary approach for the vendored/native components. Acceptance: running the zig build produces the binary artifacts the repo previously committed (at minimum: Tcl9 library for one target platform); existing Tcl9-zig experiments brought into the project; `tclsh src/make.tcl` integrates with the zig build so a normal project build retrieves/builds binaries via zig when not present; no binary artifacts need to be committed for the build to succeed on a clean checkout with the zig toolchain available. ## Context The repo currently commits binary dependencies (Tcl9 shared library, twapi, other native extensions) in VFS, vendorlib, vendormodules, and bootsupport folders. G-004's aim is to remove these, but that requires an automated way to rebuild them from source. This goal is that mechanism. The intended build infrastructure is the **zig language and build system**, chosen for its cross-platform compilation support. Experiments building Tcl9 with zig (instead of the standard autoconf/make Tcl build) have already been performed outside this project and will be brought in for expansion. Zig's `build.zig` provides a cross-platform build graph that can compile C code (Tcl is C) for multiple targets from a single toolchain, which is why it was chosen over the standard Tcl build system for this purpose. The binary dependencies to cover include at minimum: - Tcl9 shared library (the core that the Punk shell runs on) - Native Tcl extensions currently vendored (e.g. twapi on Windows, tcllibc) - Any other native components the build currently expects to find committed This goal is the primary mechanism for G-004's outcome. It is independent of and parallel to G-006 (pre-built download); the two provide alternative paths to the same artifacts. ## Approach 1. **Bring in the Tcl9-zig experiment.** Import the existing out-of-project Tcl9-zig build experiment into the repo (likely under `src/runtime/` or a new top-level build directory). Get it building Tcl9 for at least one target platform. 2. **Expand to other dependencies.** Extend the zig build to cover the other native binary dependencies currently committed (twapi, tcllibc, etc.), one at a time. Each dependency gets a zig build target that produces the same artifact shape the repo currently commits. 3. **Integrate with make.tcl.** `tclsh src/make.tcl` is the existing build entry point. Wire it so that when a required binary artifact is not present, it invokes the zig build to produce it (or, per G-006, offers the download path). The integration must not require a separate manual zig step for a normal `make.tcl project` build when the zig toolchain is available. 4. **Document the zig toolchain prerequisite.** The zig toolchain is a build-time prerequisite for this path. Document how to obtain it (install instructions, version pinning). Consider auto-detection with an actionable message when zig is absent, and defer to G-006's download path or an error depending on what the user has configured. 5. **Cross-platform targets.** The project's primary target is Windows (`win32-x86_64`); Linux, macOS, FreeBSD are secondary. The zig build should support at least the primary target first, with the cross-platform capability used to add the others. ## Alternatives considered - **Standard Tcl build (autoconf/make).** Rejected for this purpose: the standard Tcl build system is platform-specific and doesn't provide the cross-platform single-toolchain compilation that zig does. The zig experiment exists precisely because the standard build was judged insufficient for this project's cross-platform needs. - **Keep committed binaries, no build infrastructure.** Rejected: this is the explicit problem G-004 exists to solve. - **CMake or other build systems.** Not chosen; the user specified zig, and the Tcl9-zig experiment already exists. Switching systems would discard the existing experiment. - **Fold the download path (G-006) into this goal.** Rejected: the consent-gating requirement on downloads is a distinct behavioural concern with its own acceptance, and the two paths are independently useful (a user with zig builds; a user without zig downloads). ## Notes - Parallel to G-006. Both produce the same artifact set; G-004's acceptance allows either path. - The zig build produces artifacts that `make.tcl` expects to find in specific locations (VFS, vendor folders). The integration must place outputs where the existing build looks for them, or update the existing build to look in the zig output locations. - The Tcl9-zig experiment is the seed; expect it to need expansion beyond Tcl9 to cover the full dependency set. Don't underestimate this — the experiment covers one component; the goal covers all committed binaries. - If the zig build for a particular dependency proves infeasible, G-006's download path is the fallback for that dependency, and the goal's acceptance is satisfied by the dependencies it does cover plus download for the rest. Document any such deferral. - No persisted prior chat on this topic was found in project sessions; the motivation is the user's stated intent and the existing Tcl9-zig experiment. - G-058 (archived) shipped the static-baseline capture/seeding that zig-built static runtimes will rely on (boot probe-loads empty-filename [info loaded] entries, seeds ifneeded mappings into fabricated interps/threads); its detail file records the runtime-shape findings (tclsfe stub replacement, composite-static exclusion) that a static-runtime build must respect - see goals/archive/G-058-static-runtime-packages.md.