build: parameterize cross-compile by TARGET_ARCH (amd64|arm64)

ober

976fc91e3476d3c4b9b7476c2b8fffb1b7f992a7

diff --git a/Makefile b/Makefile
index 0418c25..095423d 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ TUI_SHIM_DIR   := $(CURDIR)/vendor/termbox2
 NATIVE_LIB_DIR := $(JERBOA_HOME)/lib
 LDPATH         := $(SHIM_DIR):$(TUI_SHIM_DIR):$(SQLITE_LIB_DIR):$(NATIVE_LIB_DIR)
 
-.PHONY: all help build gen run test test-providers clean repl binary install tui-shim run-tui jcode-musl linux linux-amd64 jcode-linux-amd64 linux-docker linux-check linux-local docker test-linux test-linux-amd64 purge-stale sqlite-shim android android-clean
+.PHONY: all help build gen run test test-providers clean repl binary install tui-shim run-tui jcode-musl linux linux-amd64 linux-arm64 jcode-linux-amd64 linux-docker linux-check linux-local docker test-linux test-linux-amd64 purge-stale sqlite-shim android android-clean
 
 all: help
 
@@ -31,7 +31,8 @@ help:
 	@echo "  binary       Build native binary (macOS)"
 	@echo "  install      Install binary to ~/.local/bin"
 	@echo "  linux        Build Linux x86_64 static binary (cross-compile from this host)"
-	@echo "  linux-amd64  Same as 'linux' (explicit arch name)"
+	@echo "  linux-amd64  Cross-compile static jcode-linux-amd64 (default)"
+	@echo "  linux-arm64  Cross-compile static jcode-linux-arm64"
 	@echo "  linux-docker Build static musl binary via Docker (slower; canonical)"
 	@echo "  linux-local  Build static musl binary on host (Linux only)"
 	@echo "  linux-check  Fast drift check for musl build path"
@@ -254,7 +255,21 @@ linux-amd64: gen
 	@command -v cargo >/dev/null 2>&1 || { \
 	  echo "ERROR: cargo not found on PATH. Install rustup from rustup.rs"; \
 	  exit 1; }
-	JERBOA_HOME=$(JERBOA_HOME) $(SCHEME) -q --libdirs "$(XC_LIBDIRS)" --script build-jcode-cross.ss
+	JERBOA_HOME=$(JERBOA_HOME) TARGET_ARCH=amd64 $(SCHEME) -q --libdirs "$(XC_LIBDIRS)" --script build-jcode-cross.ss
+
+linux-arm64: gen
+	@command -v aarch64-linux-musl-gcc >/dev/null 2>&1 || { \
+	  echo "ERROR: aarch64-linux-musl-gcc not found on PATH."; \
+	  echo "Install with: brew install FiloSottile/musl-cross/musl-cross"; \
+	  exit 1; }
+	@test -d $(JERBOA_HOME)/.chez-cross-tarm64le || { \
+	  echo "ERROR: cross-built Chez not found at $(JERBOA_HOME)/.chez-cross-tarm64le"; \
+	  echo "Build it with: cd $(JERBOA_HOME) && make chez-cross-tarm64le"; \
+	  exit 1; }
+	@command -v cargo >/dev/null 2>&1 || { \
+	  echo "ERROR: cargo not found on PATH. Install rustup from rustup.rs"; \
+	  exit 1; }
+	JERBOA_HOME=$(JERBOA_HOME) TARGET_ARCH=arm64 $(SCHEME) -q --libdirs "$(XC_LIBDIRS)" --script build-jcode-cross.ss
 
 # Friendly alias — same target, more explicit name.
 jcode-linux-amd64: linux-amd64
@@ -309,6 +324,7 @@ jcode-freebsd-amd64: freebsd-amd64
 # `make build` from a FreeBSD host instead.
 freebsd: freebsd-amd64
 
+
 clean:
 	find lib/jcode -name "*.sls" -delete 2>/dev/null; true
 	find . -name "*.so" -delete
diff --git a/build-jcode-cross.ss b/build-jcode-cross.ss
index f8ae3c1..0f19c7e 100644
--- a/build-jcode-cross.ss
+++ b/build-jcode-cross.ss
@@ -1,17 +1,19 @@
 #!chezscheme
-;;; build-jcode-cross.ss — Cross-compile jcode from macOS arm64 to Linux x86_64 musl
+;;; build-jcode-cross.ss — Cross-compile jcode from macOS to Linux musl
 ;;;
 ;;; Usage:
-;;;   JERBOA_HOME=/Users/user/mine/jerboa scheme --libdirs <libs> \
-;;;     --script build-jcode-cross.ss
+;;;   JERBOA_HOME=/Users/user/mine/jerboa TARGET_ARCH=amd64 scheme \
+;;;     --libdirs <libs> --script build-jcode-cross.ss
+;;;
+;;; TARGET_ARCH selects the cross target:
+;;;   amd64 (default) — chez ta6le    + x86_64-linux-musl-gcc  → jcode-linux-amd64
+;;;   arm64           — chez tarm64le + aarch64-linux-musl-gcc → jcode-linux-arm64
 ;;;
 ;;; Cross-compile analogue of build-jcode-musl.ss that runs on a non-Linux host.
 ;;; Uses:
-;;;   - $JERBOA_HOME/.chez-cross-ta6le/   — cross-built Chez install
-;;;   - $JERBOA_HOME/build/chez/xc-ta6le/s/xpatch — host compiler → ta6le emit
-;;;   - x86_64-linux-musl-gcc             — C compile + final static link
-;;;
-;;; Produces: jcode-linux-amd64  (static Linux x86_64 ELF, no shared library deps)
+;;;   - $JERBOA_HOME/.chez-cross-<machine>/   — cross-built Chez install
+;;;   - $JERBOA_HOME/build/chez/xc-<machine>/s/xpatch — host compiler emit mode
+;;;   - <toolchain>-linux-musl-gcc            — C compile + final static link
 ;;;
 ;;; This is the "WPO as program" pattern: main-binary.ss + all imports are
 ;;; bundled into one .so via compile-whole-program, loaded at runtime via
@@ -23,11 +25,26 @@
 (define jerboa-home
   (or (getenv "JERBOA_HOME") "/Users/user/mine/jerboa"))
 
-(define cross-prefix (format "~a/.chez-cross-ta6le" jerboa-home))
-(define xpatch       (format "~a/build/chez/xc-ta6le/s/xpatch" jerboa-home))
-(define cross-cc     (or (getenv "CROSS_CC") "x86_64-linux-musl-gcc"))
+(define target-arch (or (getenv "TARGET_ARCH") "amd64"))
+
+;; Per-arch dispatch: (arch chez-machine c-toolchain rust-target output-name)
+(define arch-table
+  '(("amd64" "ta6le"    "x86_64-linux-musl-gcc"  "x86_64-unknown-linux-musl"  "jcode-linux-amd64")
+    ("arm64" "tarm64le" "aarch64-linux-musl-gcc" "aarch64-unknown-linux-musl" "jcode-linux-arm64")))
+
+(define arch-row
+  (or (assoc target-arch arch-table)
+      (error 'build-jcode-cross
+             (format "unknown TARGET_ARCH (expected amd64|arm64): ~a" target-arch))))
+
+(define chez-machine (list-ref arch-row 1))
+(define rust-target  (list-ref arch-row 3))
+
+(define cross-prefix (format "~a/.chez-cross-~a" jerboa-home chez-machine))
+(define xpatch       (format "~a/build/chez/xc-~a/s/xpatch" jerboa-home chez-machine))
+(define cross-cc     (or (getenv "CROSS_CC") (list-ref arch-row 2)))
 
-(define output       "jcode-linux-amd64")
+(define output       (list-ref arch-row 4))
 (define entry-script "main-binary.ss")
 
 ;; jcode uses only this subset of jerboa-native-rs features:
@@ -38,8 +55,8 @@
 
 (define jerboa-native-a
   (or (getenv "JERBOA_NATIVE_A")
-      (format "~a/jerboa-native-rs/target/x86_64-unknown-linux-musl/release/libjerboa_native.a"
-              jerboa-home)))
+      (format "~a/jerboa-native-rs/target/~a/release/libjerboa_native.a"
+              jerboa-home rust-target)))
 
 (define cross-csv-dir
   (let ([lib (format "~a/lib" cross-prefix)])
@@ -52,7 +69,7 @@
                             entries)])
       (when (null? csvs)
         (error 'build-jcode-cross "no csv* in cross lib" lib))
-      (format "~a/~a/ta6le" lib (car csvs)))))
+      (format "~a/~a/~a" lib (car csvs) chez-machine))))
 
 (define (require-file p)
   (unless (file-exists? p)
@@ -79,8 +96,8 @@
 ;; set, rebuild to match what jcode needs. Sentinel file records features.
 
 (define native-features-sentinel
-  (format "~a/jerboa-native-rs/target/x86_64-unknown-linux-musl/release/.built-with-~a"
-          jerboa-home
+  (format "~a/jerboa-native-rs/target/~a/release/.built-with-~a"
+          jerboa-home rust-target
           (let ([s (string-copy cargo-features)])
             (let loop ([i 0])
               (cond [(= i (string-length s)) s]
@@ -139,8 +156,8 @@
 
 (define (rebuild-native-lib!)
   (let* ([nrs-dir (format "~a/jerboa-native-rs" jerboa-home)]
-         [cargo-args (format "build --release --no-default-features --features ~a --target x86_64-unknown-linux-musl"
-                             cargo-features)]
+         [cargo-args (format "build --release --no-default-features --features ~a --target ~a"
+                             cargo-features rust-target)]
          [via-rustup
           (and rustup-bin-dir
                (format "cd '~a' && env PATH='~a':$PATH RUSTC='~a/rustc' '~a/cargo' ~a"
@@ -150,11 +167,13 @@
                   (try-cargo-build via-path))])
     (unless ok?
       (error 'build-jcode-cross
-        (string-append
-         "failed to build jerboa-native-rs for x86_64-unknown-linux-musl. "
-         "Required: `rustup target add x86_64-unknown-linux-musl`, plus the "
-         "FiloSottile/musl-cross toolchain on PATH so cargo finds "
-         "x86_64-linux-musl-gcc as the linker.")))
+        (format
+         (string-append
+          "failed to build jerboa-native-rs for ~a. "
+          "Required: `rustup target add ~a`, plus the "
+          "FiloSottile/musl-cross toolchain on PATH so cargo finds "
+          "~a as the linker.")
+         rust-target rust-target cross-cc)))
     (unless (file-exists? jerboa-native-a)
       (error 'build-jcode-cross "cargo succeeded but .a missing" jerboa-native-a))
     (call-with-output-file native-features-sentinel
@@ -218,7 +237,7 @@
 
 ;; ── Stage 1: load xpatch (target=ta6le emit mode) ──────────────────────────
 (define orig-libdirs (library-directories))
-(printf "==> [1/6] loading xpatch (compiler -> ta6le emit mode)~n")
+(printf "==> [1/6] loading xpatch (compiler -> ~a emit mode)~n" chez-machine)
 (load xpatch)
 (library-directories orig-libdirs)
 
@@ -533,7 +552,7 @@
 (restore-patched-files!)
 
 ;; Clean up intermediate compile-program outputs so the next dev cycle on
-;; host scheme doesn't pick up ta6le-flavored .so files.
+;; host scheme doesn't pick up cross-flavored .so files.
 (for-each (lambda (f)
             (when (file-exists? f) (delete-file f)))
   '("main-binary.so" "main-binary.wpo"))