Cross-compile jerbuild for Linux + FreeBSD
ober
ea29e9c73c6b162663a62a99fac8689b68955423
--- a/Makefile +++ b/Makefile @@ -179,6 +179,26 @@ jerbuild-smoke: jerbuild exit 1; \ fi +# Cross-compiled jerbuild. Drives support/build-jerbuild.sh with TARGET_* env, +# producing ./jerbuild-<machine> alongside the host ./jerbuild. +# +# Usage: +# make jerbuild-cross CHEZ_TARGET_MACHINE=ta6le CROSS_CC=x86_64-linux-musl-gcc +# make jerbuild-cross CHEZ_TARGET_MACHINE=tarm64le CROSS_CC=aarch64-linux-musl-gcc +# make jerbuild-cross CHEZ_TARGET_MACHINE=ta6fb CROSS_CC=$$PWD/support/cross-cc-freebsd-amd64 +.PHONY: jerbuild-cross +jerbuild-cross: chez build chez-cross + @test -n "$(CHEZ_TARGET_MACHINE)" \ + || { echo "ERROR: set CHEZ_TARGET_MACHINE=<machine-type>" >&2; exit 1; } + SCHEME=$(SCHEME) \ + JERBOA_CHEZ_PREFIX=$(CHEZ_PREFIX) \ + JERBOA_CROSS_PREFIX=$(CHEZ_CROSS_PREFIX) \ + JERBOA_XPATCH=$(CHEZ_XPATCH) \ + TARGET_MACHINE=$(CHEZ_TARGET_MACHINE) \ + CC="$(CROSS_CC)" \ + OUTPUT=jerbuild-$(CHEZ_TARGET_MACHINE) \ + support/build-jerbuild.sh + # ── Cross-compilation ──────────────────────────────────────────────────────── # Override these to cross-compile: # CHEZ_TARGET_MACHINE — Chez machine type (e.g. ta6osx, ta6le, tarm64le, ta6fb) --- a/support/build-jerbuild.sh +++ b/support/build-jerbuild.sh @@ -7,15 +7,15 @@ # or a Chez install. # # Usage: -# support/build-jerbuild.sh -# -# Output: -# ./jerbuild — the binary +# support/build-jerbuild.sh # native host build → ./jerbuild # -# Runtime usage of the produced binary: -# jerbuild <src-dir> <lib-dir> — transpile .ss → .sls -# jerbuild --jerboa-home — extract bundled stdlib, print its path -# jerbuild --version — print version + bundled-lib hash +# # cross build → ./jerbuild-<target> (driven by Makefile's jerbuild-<os-arch>) +# TARGET_MACHINE=ta6le \ +# JERBOA_CROSS_PREFIX=.chez-cross-ta6le \ +# JERBOA_XPATCH=build/chez/xc-ta6le/s/xpatch \ +# CC=x86_64-linux-musl-gcc \ +# OUTPUT=jerbuild-ta6le \ +# support/build-jerbuild.sh set -eu @@ -25,26 +25,81 @@ JERBOA_CHEZ_PREFIX="${JERBOA_CHEZ_PREFIX:-$JERBOA_HOME/.chez}" CC="${CC:-cc}" OUTPUT="${OUTPUT:-jerbuild}" +# ── Cross-compilation parameters (all optional; unset = native build) ──────── +# TARGET_MACHINE Chez machine type to emit (e.g. ta6osx, ta6le). +# JERBOA_CROSS_PREFIX Install prefix of the cross-built Chez. +# JERBOA_XPATCH Path to xc-<target>/s/xpatch (makes host Scheme emit target FASL). +TARGET_MACHINE="${TARGET_MACHINE:-}" +JERBOA_CROSS_PREFIX="${JERBOA_CROSS_PREFIX:-}" +JERBOA_XPATCH="${JERBOA_XPATCH:-}" + +if [ -n "$TARGET_MACHINE" ]; then + CROSS_BUILD=yes + [ -n "$JERBOA_CROSS_PREFIX" ] || { echo "ERROR: TARGET_MACHINE set but JERBOA_CROSS_PREFIX is not" >&2; exit 1; } + [ -n "$JERBOA_XPATCH" ] || { echo "ERROR: TARGET_MACHINE set but JERBOA_XPATCH is not" >&2; exit 1; } + [ -f "$JERBOA_XPATCH" ] || { echo "ERROR: xpatch not found at $JERBOA_XPATCH" >&2; exit 1; } +else + CROSS_BUILD=no +fi + cd "$JERBOA_HOME" [ -x "$SCHEME" ] || { echo "ERROR: scheme not found at $SCHEME" >&2; exit 1; } [ -f "jerbuild.ss" ] || { echo "ERROR: jerbuild.ss not found in $JERBOA_HOME" >&2; exit 1; } +# ── Derive target OS from machine type (le=Linux, osx=macOS, fb=FreeBSD) ───── +machine_type_os() { + case "$1" in + *osx) echo Darwin ;; + *nt) echo Windows ;; + *fb) echo FreeBSD ;; + *ob) echo OpenBSD ;; + *nb) echo NetBSD ;; + *s2) echo Solaris ;; + *le|*) echo Linux ;; + esac +} + HOST_OS=$(uname -s) -case "$HOST_OS" in - Darwin) OS_LIBS="-lm -lpthread -lncurses -liconv" ;; - Linux) OS_LIBS="-lm -ldl -lpthread -lncurses" ;; - FreeBSD) OS_LIBS="-lm -lpthread -lncurses -L/usr/local/lib -liconv" ;; - *) OS_LIBS="-lm -lpthread -lncurses" ;; -esac - -MACHINE_TYPE=$("$SCHEME" -q <<'EOF' +if [ "$CROSS_BUILD" = yes ]; then + TARGET_OS=$(machine_type_os "$TARGET_MACHINE") +else + TARGET_OS="$HOST_OS" +fi + +# Cross builds use `make chez-cross` which configures Chez with --disable-curses +# --disable-x11 --disable-iconv by default, so libkernel.a won't reference those. +# Native builds link them because host Chez is built --as-is. +if [ "$CROSS_BUILD" = yes ]; then + case "$TARGET_OS" in + FreeBSD) OS_LIBS="-lm -lpthread" ;; + Darwin) OS_LIBS="-lm -lpthread" ;; + Linux) OS_LIBS="-lm -ldl -lpthread -static" ;; + *) OS_LIBS="-lm -lpthread" ;; + esac +else + case "$HOST_OS" in + Darwin) OS_LIBS="-lm -lpthread -lncurses -liconv" ;; + Linux) OS_LIBS="-lm -ldl -lpthread -lncurses" ;; + FreeBSD) OS_LIBS="-lm -lpthread -lncurses -L/usr/local/lib -liconv" ;; + *) OS_LIBS="-lm -lpthread -lncurses" ;; + esac +fi + +# ── Determine machine type + Chez install dir ─────────────────────────────── +if [ "$CROSS_BUILD" = yes ]; then + MACHINE_TYPE="$TARGET_MACHINE" + CSV_SEARCH_PREFIX="$JERBOA_CROSS_PREFIX/lib" +else + MACHINE_TYPE=$("$SCHEME" -q <<'EOF' (display (machine-type)) (exit) EOF ) + CSV_SEARCH_PREFIX="$JERBOA_CHEZ_PREFIX/lib" +fi CSV_DIR="" -for prefix in "$JERBOA_CHEZ_PREFIX/lib" /usr/local/lib /usr/lib /usr/lib64 /opt/homebrew/lib /opt/local/lib; do +for prefix in "$CSV_SEARCH_PREFIX" /usr/local/lib /usr/lib /usr/lib64 /opt/homebrew/lib /opt/local/lib; do for d in "$prefix"/csv*/"$MACHINE_TYPE"; do if [ -f "$d/libkernel.a" ] && [ -f "$d/scheme.h" ] && [ -f "$d/petite.boot" ]; then CSV_DIR="$d" @@ -52,10 +107,15 @@ for prefix in "$JERBOA_CHEZ_PREFIX/lib" /usr/local/lib /usr/lib /usr/lib64 /opt/ fi done done -[ -n "$CSV_DIR" ] || { echo "ERROR: no Chez install found for $MACHINE_TYPE" >&2; exit 1; } +[ -n "$CSV_DIR" ] || { echo "ERROR: no Chez install found for $MACHINE_TYPE under $CSV_SEARCH_PREFIX" >&2; exit 1; } echo "=== jerbuild binary build ===" -echo " Host: $HOST_OS, $MACHINE_TYPE" +if [ "$CROSS_BUILD" = yes ]; then + echo " Mode: CROSS ($HOST_OS -> $TARGET_OS, $MACHINE_TYPE)" + echo " xpatch: $JERBOA_XPATCH" +else + echo " Mode: native ($HOST_OS, $MACHINE_TYPE)" +fi echo " CC: $CC" echo " Chez: $CSV_DIR" echo " Out: ./$OUTPUT" @@ -67,7 +127,7 @@ BUNDLE_TAR=$(mktemp "/tmp/jerbuild-bundle.XXXXXX.tar") trap 'rm -rf "$OBJ_DIR" "$WPO_SO" "$BUNDLE_TAR" petite_boot.h scheme_boot.h program_boot.h bundle_tar.h bundle_meta.h "${OUTPUT}-main.c"' EXIT echo "==> [1/5] WPO compile jerbuild.ss" -"$SCHEME" --libdirs "$JERBOA_HOME/lib" \ +JERBOA_XPATCH="$JERBOA_XPATCH" "$SCHEME" --libdirs "$JERBOA_HOME/lib" \ --script "$JERBOA_HOME/support/build-boot.ss" \ jerbuild.ss "$WPO_SO" "$OBJ_DIR" echo ""