punix build¶
Type-check + realise every package module declared in FILE. Batch-resilient: a per-package failure is reported, the rest still build.
Synopsis¶
Flow¶
FILE → parse → check → close build-closure (E7)
│
▼
for each package module:
canonical derivation → hash → store path
if path exists & valid: cache hit
else: realise (sandbox, prepare_source, run recipe)
writes <store_path>/built marker last
Output¶
→ building 3 package(s) into /Users/you/.punix/store
per-package build logs: /Users/you/.punix/punix-build-logs/<module>.log
[1/3] Caddy
[2/3] Forgejo
[3/3] Postgres
[1] realise Caddy
[2] cache hit Forgejo
[3] realise Postgres
ok Caddy /Users/you/.punix/store/a1b2…-caddy-2.9.1
ok Forgejo /Users/you/.punix/store/c3d4…-forgejo-9.0.3
FAIL Postgres build failed (rc=2) — last stderr: ld: cannot find -lreadline (log: ./punix-build-logs/Postgres.log)
3 packages: 2 ok, 1 failed
Per-package lines:
ok\tMODULE\tPATH— successful realise (or cache hit).FAIL\tMODULE\tDETAIL— failure;DETAILends with(log: PATH)pointing at the full stderr/stdout dump.
The format is tab-separated so you can pipe punix build into other tools (awk, cut, jq via a quick transform).
Exit codes¶
0— every package succeeded.1— whole-program defect: located[E#]before any realise ran (parse/type/build-closure error). No packages were built.3— at least one package realise failed. Other packages may have succeeded; see the per-line output.
Flags¶
--dry-run— useRealiseDryRun: compute every store path, don't build. Printsdry-run\tMODULE\tPATH. Useful for scripts that need store paths without paying the build cost; also the underpinning ofpunix store path.--store-root PATH— store location. Default~/.punix/store.--scenario NAME— evaluate under the named scenario (see Modules).--only MODULE[,MODULE2,...]— limit the build to a list of modules and their transitive deps.--bootstrap MODE— bootstrap trust policy:fast/seeded/source/bootstrappable. Default:$PUNIX_BOOTSTRAP_MODEorseeded. Violations abort the run before any recipe builds — seeinstall --bootstrapor runpunix help bootstrap.
Build closure pre-pass — [E7]¶
Before any realise runs, the build-closure pass walks the package graph and verifies host-side prerequisites:
- Every
deps = […]reference resolves to a module that itself has a recipe ([E7]if it doesn't). - The closure is acyclic (
[E7]if a cycle is detected).
This catches the largest class of "I forgot to declare X" errors before any build runs — the operator gets one located error instead of a partial-build with one module's stderr to read.
Recipes and identity¶
recipe = "std.autotools" in PCL maps to a recipe under src/punix/realise/recipes_lib/std/autotools.py. The recipe's identity (name + content-hash of its .py + sibling files) is part of the canonical derivation — edit the recipe ⇒ every package using it gets a new store path ⇒ rebuild. The conformance suite has a dedicated test for this against a recipe-hook edit.
→ Recipes for the shipped registry.
Examples¶
# Build a single PCL file
punix build hello.pcl
# Build everything under pkgs/, prod scenario
punix build pkgs/ --scenario Prod
# Compute store paths without building (cheap; powers IDE integration)
punix build hello.pcl --dry-run
# Different store root for hermetic testing
punix build hello.pcl --store-root /tmp/test-store
Related¶
punix check— type-check (no realise).punix store path— single-package predicted-path lookup.- Reference: error codes E7, E10–E13 — realise-time error surface.