commit 22ad7bf0fac945c332a1f325cd292508bedb4953
parent 5757513857ba4807e5642573a662659b4a4ad398
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Fri, 24 Apr 2026 17:05:32 -0700
Pass ARCH via env, drop arg-list noise from script invocations
Every script in scripts/ now reads ARCH from its environment and derives
the per-arch fixed paths (P1/P1-$ARCH.M1, vendor/seed/$ARCH/ELF.hex2,
build/$ARCH/tools/, build/$ARCH/m1pp, build/$ARCH/.work/$NAME) from
that. Only the variable per-call inputs (source, output) are passed
positionally.
Make's PODMAN macro now adds `-e ARCH=$(1)`, so any boot-* script
invoked through it sees the arch automatically. Lint runs `ARCH=$* sh
scripts/lint.sh <src>` from the recipe.
Concretely:
boot1.sh ARCH only (was <arch> <out-dir>)
boot2.sh ARCH only (already)
boot-build-p1.sh ARCH + src out (was 6 positional args)
boot-build-p1pp.sh ARCH + src out (was 8 positional args)
lint.sh ARCH + src(s) (was <table> <src>...)
run-tests.sh passes ARCH= via container env to boot-* calls
Make rule recipes go from multi-line continuations to single calls:
$(call PODMAN,$*) sh scripts/boot-build-p1.sh M1pp/M1pp.P1 $@
Verified: make all + make hello + make run print "Hello, World!"; aarch64
m1pp suite 20/20 in ~6s.
Diffstat:
7 files changed, 78 insertions(+), 101 deletions(-)
diff --git a/Makefile b/Makefile
@@ -42,7 +42,10 @@ TOOLS_DIR := $(OUT_DIR)/tools
IMAGE_STAMP := $(OUT_DIR)/.image
# All container invocations go through this. Just env/args + one named
-# script in scripts/; never inline shell.
+# script in scripts/; never inline shell. Every script reads ARCH from
+# the env and derives all its fixed paths (P1 table, ELF header, tools
+# dir, etc.) from that — only per-call args (source, output) are passed
+# positionally.
#
# --tmpfs /tmp: backstop for the stage0 tools' per-byte fputc/fgetc. Without
# it /tmp falls through to the container overlay (still backed by virtiofs
@@ -50,6 +53,7 @@ IMAGE_STAMP := $(OUT_DIR)/.image
# byte. Real RAM tmpfs collapses that to local memory access.
PODMAN = podman run --rm --pull=never --platform $(PLATFORM_$(1)) \
--tmpfs /tmp:size=512M \
+ -e ARCH=$(1) \
-v $(CURDIR):/work -w /work boot2-busybox:$(1)
# --- Targets --------------------------------------------------------------
@@ -90,8 +94,7 @@ $(TOOLS_M0): build/%/tools/M0: scripts/boot1.sh build/%/.image \
vendor/seed/%/hex1.hex0 vendor/seed/%/hex2.hex1 \
vendor/seed/%/catm.hex2 vendor/seed/%/M0.hex2 \
vendor/seed/%/ELF.hex2
- mkdir -p build/$*/tools
- $(call PODMAN,$*) sh scripts/boot1.sh $* build/$*/tools
+ $(call PODMAN,$*) sh scripts/boot1.sh
# --- Pre-pruned P1 backend tables -----------------------------------------
#
@@ -132,22 +135,16 @@ P1_BUILD_DEPS = scripts/lint.sh scripts/boot-build-p1.sh \
vendor/seed/%/ELF.hex2 P1/P1-%.M1
$(M1PP_BINS): build/%/m1pp: M1pp/M1pp.P1 $(P1_BUILD_DEPS)
- sh scripts/lint.sh P1/P1-$*.M1 M1pp/M1pp.P1
- $(call PODMAN,$*) sh scripts/boot-build-p1.sh \
- P1/P1-$*.M1 M1pp/M1pp.P1 vendor/seed/$*/ELF.hex2 \
- build/$*/.work/m1pp build/$*/tools $@
+ ARCH=$* sh scripts/lint.sh M1pp/M1pp.P1
+ $(call PODMAN,$*) sh scripts/boot-build-p1.sh M1pp/M1pp.P1 $@
$(POKEM_BINS): build/%/pokem: pokem/pokem.P1 $(P1_BUILD_DEPS)
- sh scripts/lint.sh P1/P1-$*.M1 pokem/pokem.P1
- $(call PODMAN,$*) sh scripts/boot-build-p1.sh \
- P1/P1-$*.M1 pokem/pokem.P1 vendor/seed/$*/ELF.hex2 \
- build/$*/.work/pokem build/$*/tools $@
+ ARCH=$* sh scripts/lint.sh pokem/pokem.P1
+ $(call PODMAN,$*) sh scripts/boot-build-p1.sh pokem/pokem.P1 $@
$(HELLO_BINS): build/%/hello: $(HELLO_SRC) $(P1_BUILD_DEPS)
- sh scripts/lint.sh P1/P1-$*.M1 $(HELLO_SRC)
- $(call PODMAN,$*) sh scripts/boot-build-p1.sh \
- P1/P1-$*.M1 $(HELLO_SRC) vendor/seed/$*/ELF.hex2 \
- build/$*/.work/hello build/$*/tools $@
+ ARCH=$* sh scripts/lint.sh $(HELLO_SRC)
+ $(call PODMAN,$*) sh scripts/boot-build-p1.sh $(HELLO_SRC) $@
run: $(OUT_DIR)/hello $(IMAGE_STAMP)
$(call PODMAN,$(ARCH)) ./$(OUT_DIR)/hello
diff --git a/scripts/boot-build-p1.sh b/scripts/boot-build-p1.sh
@@ -1,12 +1,12 @@
#!/bin/sh
## boot-build-p1.sh — in-container .P1/.M1 -> ELF.
##
-## Assumes a pre-pruned P1 backend table (P1/P1-<arch>.M1). No prune step
-## at build time — that one-time work lives in scripts/prune-p1-table.sh
-## and the result is checked in.
+## Pure transformation. Caller (the Makefile) ensures every fixed-path
+## input below already exists. Only the variable per-call inputs (source,
+## output binary) come in as args.
##
## Pipeline:
-## cat <table> <src> -> /tmp/combined.M1
+## cat <P1/P1-$ARCH.M1> <src> -> /tmp/combined.M1
## M0 /tmp/combined.M1 -> /tmp/prog.hex2
## catm /tmp/elf.hex2 /tmp/prog.hex2 -> /tmp/linked.hex2
## hex2-0 /tmp/linked.hex2 -> $OUT
@@ -14,20 +14,22 @@
## Stages through /tmp because the stage0 tools do one syscall per byte;
## virtiofs round-trips would dominate otherwise.
##
-## Usage: boot-build-p1.sh <table.M1> <src> <ELF.hex2> <work-dir>
-## <tools-dir> <out>
+## Env: ARCH=aarch64|amd64|riscv64
+## Usage: boot-build-p1.sh <src> <out>
set -eu
-[ "$#" -eq 6 ] || { echo "usage: $0 <table.M1> <src> <ELF.hex2> <work-dir> <tools-dir> <out>" >&2; exit 2; }
+: "${ARCH:?ARCH must be set}"
+[ "$#" -eq 2 ] || { echo "usage: ARCH=<arch> $0 <src> <out>" >&2; exit 2; }
-TABLE=$1
-SRC=$2
-ELF_HDR=$3
-WORK=$4
-TOOLS=$5
-OUT=$6
+SRC=$1
+OUT=$2
+TABLE=P1/P1-$ARCH.M1
+ELF_HDR=vendor/seed/$ARCH/ELF.hex2
+TOOLS=build/$ARCH/tools
+NAME=$(basename "$SRC" | sed 's/\.[^.]*$//')
+WORK=build/$ARCH/.work/$NAME
mkdir -p "$WORK" "$(dirname "$OUT")"
cat "$TABLE" "$SRC" > /tmp/combined.M1
diff --git a/scripts/boot-build-p1pp.sh b/scripts/boot-build-p1pp.sh
@@ -1,33 +1,35 @@
#!/bin/sh
## boot-build-p1pp.sh — in-container .P1pp -> ELF.
##
-## Pipeline:
-## cat <P1-arch.M1pp> <P1.M1pp> <src.P1pp> -> /tmp/combined.M1pp
-## m1pp /tmp/combined.M1pp -> /tmp/expanded.M1
-## M0 /tmp/expanded.M1 -> /tmp/prog.hex2
-## catm /tmp/elf.hex2 /tmp/prog.hex2 -> /tmp/linked.hex2
-## hex2-0 /tmp/linked.hex2 -> $OUT
+## Pure transformation. Caller (the Makefile) ensures every fixed-path
+## input below already exists, including the per-arch self-hosted m1pp
+## ELF binary (build/$ARCH/m1pp, built by boot2.sh / boot-build-p1.sh).
##
-## Uses the per-arch self-hosted m1pp ELF (built by boot2.sh /
-## boot-build-p1.sh against M1pp/M1pp.P1).
+## Pipeline:
+## cat <P1/P1-$ARCH.M1pp> <P1/P1.M1pp> <src> -> /tmp/combined.M1pp
+## m1pp /tmp/combined.M1pp -> /tmp/expanded.M1
+## M0 /tmp/expanded.M1 -> /tmp/prog.hex2
+## catm /tmp/elf.hex2 /tmp/prog.hex2 -> /tmp/linked.hex2
+## hex2-0 /tmp/linked.hex2 -> $OUT
##
-## Usage: boot-build-p1pp.sh <backend.M1pp> <frontend.M1pp> <src.P1pp>
-## <ELF.hex2> <work-dir> <m1pp-bin>
-## <tools-dir> <out>
+## Env: ARCH=aarch64|amd64|riscv64
+## Usage: boot-build-p1pp.sh <src> <out>
set -eu
-[ "$#" -eq 8 ] || { echo "usage: $0 <backend.M1pp> <frontend.M1pp> <src.P1pp> <ELF.hex2> <work-dir> <m1pp-bin> <tools-dir> <out>" >&2; exit 2; }
+: "${ARCH:?ARCH must be set}"
+[ "$#" -eq 2 ] || { echo "usage: ARCH=<arch> $0 <src> <out>" >&2; exit 2; }
-BACKEND=$1
-FRONTEND=$2
-SRC=$3
-ELF_HDR=$4
-WORK=$5
-M1PP_BIN=$6
-TOOLS=$7
-OUT=$8
+SRC=$1
+OUT=$2
+BACKEND=P1/P1-$ARCH.M1pp
+FRONTEND=P1/P1.M1pp
+ELF_HDR=vendor/seed/$ARCH/ELF.hex2
+TOOLS=build/$ARCH/tools
+M1PP_BIN=build/$ARCH/m1pp
+NAME=$(basename "$SRC" .P1pp)
+WORK=build/$ARCH/.work/$NAME
mkdir -p "$WORK" "$(dirname "$OUT")"
cat "$BACKEND" "$FRONTEND" "$SRC" > /tmp/combined.M1pp
diff --git a/scripts/boot1.sh b/scripts/boot1.sh
@@ -3,8 +3,11 @@
##
## In-container script. Brings up M0/hex2-0/catm from the ~400-byte
## hex0-seed by chaining stage0-posix's first three phases. All produced
-## binaries are target-arch Linux ELF and land in $OUT as:
-## hex0, hex1, hex2-0, catm, M0
+## binaries are target-arch Linux ELF.
+##
+## Inputs (read): vendor/seed/$ARCH/{hex0-seed,hex0.hex0,hex1.hex0,
+## hex2.hex1,catm.hex2,M0.hex2,ELF.hex2}
+## Outputs: build/$ARCH/tools/{hex0,hex1,hex2-0,catm,M0}
##
## Phase map (stage0-posix mescc-tools-{seed,mini}-kaem.kaem phases 0-3):
## 0) hex0-seed + hex0.hex0 -> hex0
@@ -14,16 +17,11 @@
## 3a) catm : ELF.hex2 + M0.hex2 -> M0.combined.hex2
## 3b) hex2-0 : M0.combined.hex2 -> M0
##
-## Inputs are read from vendor/seed/<arch>/ (vendored upstream).
-##
-## Usage: boot1.sh <arch> <out-dir>
-## arch: aarch64 | amd64 | riscv64
-## out-dir: path (relative to /work) where tool binaries should land
+## Env: ARCH=aarch64|amd64|riscv64
set -eu
-ARCH=$1
-OUT=$2
+: "${ARCH:?ARCH must be set}"
case "$ARCH" in
aarch64|amd64|riscv64) ;;
@@ -31,6 +29,7 @@ case "$ARCH" in
esac
S=vendor/seed/$ARCH
+OUT=build/$ARCH/tools
mkdir -p "$OUT"
## Build everything in /tmp (RAM tmpfs — see PODMAN macro in Makefile),
diff --git a/scripts/boot2.sh b/scripts/boot2.sh
@@ -2,34 +2,21 @@
## boot2.sh — stage 2 of the bootstrap chain.
##
## In-container script. Builds the M1pp expander and pokem ELFs from the
-## checked-in pre-pruned P1 backend table (P1/P1-<arch>.M1) plus their
-## sources. Calls scripts/boot-build-p1.sh internally.
+## checked-in pre-pruned P1 backend table (P1/P1-$ARCH.M1) plus their
+## sources, by calling scripts/boot-build-p1.sh.
##
-## Output (relative to repo root, /work in container):
-## build/<arch>/m1pp, build/<arch>/pokem
+## Outputs: build/$ARCH/m1pp, build/$ARCH/pokem
##
-## Usage: boot2.sh <arch>
+## Env: ARCH=aarch64|amd64|riscv64
set -eu
-[ "$#" -eq 1 ] || { echo "usage: $0 <arch>" >&2; exit 2; }
-
-ARCH=$1
+: "${ARCH:?ARCH must be set}"
case "$ARCH" in
aarch64|amd64|riscv64) ;;
*) echo "boot2.sh: unsupported arch '$ARCH'" >&2; exit 1 ;;
esac
-TABLE=/work/P1/P1-$ARCH.M1
-ELF_HDR=/work/vendor/seed/$ARCH/ELF.hex2
-TOOLS=/work/build/$ARCH/tools
-OUT=/work/build/$ARCH
-
-sh /work/scripts/boot-build-p1.sh \
- "$TABLE" /work/M1pp/M1pp.P1 "$ELF_HDR" \
- "$OUT/.work/m1pp" "$TOOLS" "$OUT/m1pp"
-
-sh /work/scripts/boot-build-p1.sh \
- "$TABLE" /work/pokem/pokem.P1 "$ELF_HDR" \
- "$OUT/.work/pokem" "$TOOLS" "$OUT/pokem"
+sh scripts/boot-build-p1.sh M1pp/M1pp.P1 build/$ARCH/m1pp
+sh scripts/boot-build-p1.sh pokem/pokem.P1 build/$ARCH/pokem
diff --git a/scripts/lint.sh b/scripts/lint.sh
@@ -13,17 +13,20 @@
## quoted literals (can span lines and carry prose like "usage: lisp")
## and `#`/`;` line comments, so the pass is written in Python.
##
-## Usage: lint.sh <p1_arch.M1> <prog.M1> [<prog.M1> ...]
+## Env: ARCH=aarch64|amd64|riscv64
+## Usage: lint.sh <prog.M1> [<prog.M1> ...]
## Exit: 0 on success; 1 + diagnostic on any missing token; 2 on misuse.
set -eu
-if [ "$#" -lt 2 ]; then
- echo "usage: $0 <p1_arch.M1> <prog.M1> [<prog.M1> ...]" >&2
+: "${ARCH:?ARCH must be set}"
+
+if [ "$#" -lt 1 ]; then
+ echo "usage: ARCH=<arch> $0 <prog.M1> [<prog.M1> ...]" >&2
exit 2
fi
-exec python3 - "$@" <<'PYEOF'
+exec python3 - "P1/P1-$ARCH.M1" "$@" <<'PYEOF'
import re
import sys
diff --git a/scripts/run-tests.sh b/scripts/run-tests.sh
@@ -63,6 +63,7 @@ run_in_container() {
arch=$1; shift
podman run --rm --pull=never --platform "$(platform_of "$arch")" \
--tmpfs /tmp:size=512M \
+ -e "ARCH=$arch" \
-v "$REPO":/work -w /work \
"boot2-busybox:$arch" "$@"
}
@@ -134,18 +135,12 @@ run_m1pp_suite() {
actual=$([ -e "$outfile" ] && cat "$outfile" || echo "")
elif [ -e "$m1_src" ]; then
bin=build/$arch/m1pp-tests/$name
- table=P1/P1-$arch.M1
- elf=vendor/seed/$arch/ELF.hex2
- work=build/$arch/.work/m1pp-tests/$name
- tools=build/$arch/tools
- if ! sh scripts/lint.sh "$table" "$m1_src" >/dev/null 2>&1 \
- || ! run_in_container "$arch" sh scripts/boot-build-p1.sh \
- "$table" "$m1_src" "$elf" "$work" "$tools" "$bin" \
+ if ! ARCH=$arch sh scripts/lint.sh "$m1_src" >/dev/null 2>&1 \
+ || ! run_in_container "$arch" sh scripts/boot-build-p1.sh "$m1_src" "$bin" \
>/dev/null 2>&1; then
report "$label" FAIL
- sh scripts/lint.sh "$table" "$m1_src" 2>&1 | sed 's/^/ /' >&2 || true
- run_in_container "$arch" sh scripts/boot-build-p1.sh \
- "$table" "$m1_src" "$elf" "$work" "$tools" "$bin" \
+ ARCH=$arch sh scripts/lint.sh "$m1_src" 2>&1 | sed 's/^/ /' >&2 || true
+ run_in_container "$arch" sh scripts/boot-build-p1.sh "$m1_src" "$bin" \
2>&1 | sed 's/^/ /' >&2 || true
continue
fi
@@ -190,18 +185,10 @@ run_p1_suite() {
for arch in $ARCHES; do
label="[$arch] $name"
bin=build/$arch/p1-tests/$name
- backend=P1/P1-$arch.M1pp
- frontend=P1/P1.M1pp
- elf=vendor/seed/$arch/ELF.hex2
- work=build/$arch/.work/p1-tests/$name
- m1pp_bin=build/$arch/m1pp
- tools=build/$arch/tools
- if ! run_in_container "$arch" sh scripts/boot-build-p1pp.sh \
- "$backend" "$frontend" "$fixture" "$elf" "$work" "$m1pp_bin" "$tools" "$bin" \
+ if ! run_in_container "$arch" sh scripts/boot-build-p1pp.sh "$fixture" "$bin" \
>/dev/null 2>&1; then
report "$label" FAIL
- run_in_container "$arch" sh scripts/boot-build-p1pp.sh \
- "$backend" "$frontend" "$fixture" "$elf" "$work" "$m1pp_bin" "$tools" "$bin" \
+ run_in_container "$arch" sh scripts/boot-build-p1pp.sh "$fixture" "$bin" \
2>&1 | sed 's/^/ /' >&2 || true
continue
fi