fix: delegate linux-amd64/arm64 to jerboa-shell-extras when extras features requested
ober
9679e26a75018a6f1c70ff9deb8fc757b7152bb3
--- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ /.jcode/ /.claude/ .gerbil-lsp-cache/ +vendor/jerboa-shell-extras/ --- a/.jerbuild.linux-amd64 +++ b/.jerbuild.linux-amd64 @@ -11,7 +11,7 @@ (cc "cc") -(os-libs "-lm -ldl -lpthread -ltinfo") +(os-libs "-lm -ldl -lpthread -ltinfo -ludev") (libdirs "_jerbuild-stage" ; stdlib patches — must shadow bundle copies "src" @@ -33,7 +33,8 @@ "_jerbuild-stage/libjerboa_native.a" "_jerbuild-stage/libjsh_coreutils.a" "_jerbuild-stage/libjerboa_ssh.a" - "_jerbuild-stage/libjerboa_fuse.a") + "_jerbuild-stage/libjerboa_fuse.a" + "_jerbuild-stage/libyubikey_native.a") ;; --export-dynamic + Sforeign_symbol registrations in main.c are how Chez ;; foreign-procedure finds symbols. --allow-multiple-definition tolerates --- a/Makefile +++ b/Makefile @@ -126,7 +126,8 @@ build: binary ensure-jerboa-tools: @set -e; \ - if [ -n "$(JERBUILD)" ] && [ -x "$(JERBUILD)" ] && "$(JERBUILD)" --jerboa-home >/dev/null 2>&1; then \ + _jb_cmd="$$(echo '$(JERBUILD)' | awk '{print $$1}')"; \ + if [ -n "$(JERBUILD)" ] && [ -x "$$_jb_cmd" ] && $(JERBUILD) --jerboa-home >/dev/null 2>&1; then \ echo "=== Using Jerboa toolchain: $(JERBUILD) ==="; \ else \ echo "=== Fetching Jerboa $(JERBOA_VERSION) release tools into $(JERBOA_TOOL_DIR) ==="; \ @@ -146,6 +147,8 @@ ensure-shell-extras: git -C "$(JERBOA_SHELL_EXTRAS_DIR)" pull --ff-only; \ fi @test -f "$(JERBOA_SHELL_EXTRAS_DIR)/Makefile" + @# Patch extras repo's build config for yubikey/udev support + sh support/patch-extras-build.sh "$(JERBOA_SHELL_EXTRAS_DIR)" configure: ensure-shell-extras @$(MAKE) -C "$(JERBOA_SHELL_EXTRAS_DIR)" configure \ @@ -539,18 +542,36 @@ yubikey-native-linux-arm64: rust-musl-target-arm64 --release --target aarch64-unknown-linux-musl --no-default-features @test -f $(XC_YUBIKEY_NATIVE_MUSL_ARM64_LIB) -linux-amd64: ensure-shell-extras stage-jsqlite ffi-shim-symbols.list vendor-deps-linux jerboa gen-embed chez-cross-amd64 rust-coreutils-linux-amd64 jerboa-native-linux-amd64 vendor-staged-libs yubikey-native-linux-amd64 - @echo "=== Wiping stale per-arch compiled artifacts (.so/.wpo/boot) ===" - @$(XC_WIPE) +linux-amd64: ensure-shell-extras vendor-deps-linux @features="$(JSH_CROSS_FEATURES)"; \ if [ -f "$(JERBOA_SHELL_EXTRAS_DIR)/Makefile" ] && echo "$$features" | grep -qE '^(all|.*embed|.*pass|.*wireguard|.*harden|.*awk|.*sed)'; then \ echo "=== Extras features detected — delegating to jerboa-shell-extras ==="; \ - $(MAKE) -C "$(JERBOA_SHELL_EXTRAS_DIR)" linux-amd64 \ - JERBOA_SHELL_DIR="$(CURDIR)" \ - JSH_CROSS_FEATURES="$(JSH_CROSS_FEATURES)" \ - JSH_FEATURES="$(JSH_FEATURES)"; \ - cp -f "$(JERBOA_SHELL_EXTRAS_DIR)/jsh-linux-amd64" "$(CURDIR)/jsh-linux-amd64"; \ + case "$$(uname -s)-$$(uname -m)" in \ + Linux-x86_64|Linux-amd64) \ + echo "=== Native Linux build via jerboa-shell-extras ==="; \ + $(MAKE) -C "$(JERBOA_SHELL_EXTRAS_DIR)" jsh-linux-native \ + JERBOA_SHELL_DIR="$(CURDIR)" \ + JSH_FEATURES="$(JSH_FEATURES)"; \ + cp -f "$(JERBOA_SHELL_EXTRAS_DIR)/jsh-linux-amd64" "$(CURDIR)/jsh-linux-amd64"; ;; \ + *) \ + echo "=== Cross-build via jerboa-shell-extras (macOS -> Linux) ==="; \ + $(MAKE) chez-cross-amd64 jerboa-native-linux-amd64 yubikey-native-linux-amd64 rust-coreutils-linux-amd64; \ + JERBOA_HOME=$(abspath $(JERBOA_HOME)) JSH_CROSS_FEATURES="$(JSH_CROSS_FEATURES)" \ + $(MAKE) -C "$(JERBOA_SHELL_EXTRAS_DIR)" _linux-amd64-delegated \ + JERBOA_SHELL_DIR="$(abspath $(CURDIR))" \ + JSH_FEATURES="$(JSH_FEATURES)" \ + JSH_CROSS_FEATURES="$(JSH_CROSS_FEATURES)" \ + XC_NATIVE_RS_DIR="$(abspath $(XC_NATIVE_RS_DIR))" \ + XC_NATIVE_MUSL_AMD64_LIB="$(abspath $(XC_NATIVE_MUSL_AMD64_LIB))" \ + XC_YUBIKEY_NATIVE_MUSL_AMD64_LIB="$(abspath $(XC_YUBIKEY_NATIVE_MUSL_AMD64_LIB))"; \ + XC_YUBIKEY_NATIVE_MUSL_AMD64_LIB="$(XC_YUBIKEY_NATIVE_MUSL_AMD64_LIB)"; \ + cp -f "$(JERBOA_SHELL_EXTRAS_DIR)/jsh-linux-amd64" "$(CURDIR)/jsh-linux-amd64"; ;; \ + esac \ else \ + echo "=== Building cross-compilation prerequisites ==="; \ + $(MAKE) stage-jsqlite ffi-shim-symbols.list jerboa gen-embed chez-cross-amd64 rust-coreutils-linux-amd64 jerboa-native-linux-amd64 vendor-staged-libs yubikey-native-linux-amd64; \ + echo "=== Wiping stale per-arch compiled artifacts (.so/.wpo/boot) ==="; \ + $(XC_WIPE); \ echo "=== Cross-building jsh-linux-amd64 (x86_64 Linux static, JSH_FEATURES=$$features) ==="; \ JERBOA_HOME=$(JERBOA_HOME) TARGET_ARCH=amd64 JSH_FEATURES="$$features" JERBOA_NATIVE_FEATURES="$(JERBOA_NATIVE_FEATURES)" JERBOA_NATIVE_A="$(XC_NATIVE_MUSL_AMD64_LIB)" YUBIKEY_NATIVE_A="$(XC_YUBIKEY_NATIVE_MUSL_AMD64_LIB)" $(SCHEME) -q --libdirs "$(XC_LIBDIRS)" --script build-jsh-cross.ss; \ fi @@ -558,18 +579,32 @@ linux-amd64: ensure-shell-extras stage-jsqlite ffi-shim-symbols.list vendor-deps @ls -lh jsh-linux-amd64 @file jsh-linux-amd64 -linux-arm64: ensure-shell-extras stage-jsqlite ffi-shim-symbols.list vendor-deps-linux jerboa gen-embed chez-cross-arm64 rust-coreutils-linux-arm64 jerboa-native-linux-arm64 vendor-staged-libs yubikey-native-linux-arm64 - @echo "=== Wiping stale per-arch compiled artifacts (.so/.wpo/boot) ===" - @$(XC_WIPE) +linux-arm64: ensure-shell-extras vendor-deps-linux @features="$(JSH_CROSS_FEATURES)"; \ if [ -f "$(JERBOA_SHELL_EXTRAS_DIR)/Makefile" ] && echo "$$features" | grep -qE '^(all|.*embed|.*pass|.*wireguard|.*harden|.*awk|.*sed)'; then \ echo "=== Extras features detected — delegating to jerboa-shell-extras ==="; \ - $(MAKE) -C "$(JERBOA_SHELL_EXTRAS_DIR)" linux-arm64 \ - JERBOA_SHELL_DIR="$(CURDIR)" \ - JSH_CROSS_FEATURES="$(JSH_CROSS_FEATURES)" \ - JSH_FEATURES="$(JSH_FEATURES)"; \ - cp -f "$(JERBOA_SHELL_EXTRAS_DIR)/jsh-linux-arm64" "$(CURDIR)/jsh-linux-arm64"; \ + case "$$(uname -s)-$$(uname -m)" in \ + Linux-aarch64|Linux-arm64) \ + echo "=== Native Linux build via jerboa-shell-extras ==="; \ + $(MAKE) -C "$(JERBOA_SHELL_EXTRAS_DIR)" jsh-linux-native \ + JERBOA_SHELL_DIR="$(CURDIR)" \ + JSH_FEATURES="$(JSH_FEATURES)"; \ + cp -f "$(JERBOA_SHELL_EXTRAS_DIR)/jsh-linux-arm64" "$(CURDIR)/jsh-linux-arm64"; ;; \ + *) \ + echo "=== Cross-build via jerboa-shell-extras (macOS -> Linux) ==="; \ + $(MAKE) chez-cross-arm64; \ + JERBOA_HOME=$(JERBOA_HOME) JSH_CROSS_FEATURES="$(JSH_CROSS_FEATURES)" \ + $(MAKE) -C "$(JERBOA_SHELL_EXTRAS_DIR)" _linux-arm64-delegated \ + JERBOA_SHELL_DIR="$(CURDIR)" \ + JSH_FEATURES="$(JSH_FEATURES)" \ + XC_NATIVE_RS_DIR="$(XC_NATIVE_RS_DIR)" \ + XC_NATIVE_MUSL_ARM64_LIB="$(XC_NATIVE_MUSL_ARM64_LIB)" \ + XC_YUBIKEY_NATIVE_MUSL_ARM64_LIB="$(XC_YUBIKEY_NATIVE_MUSL_ARM64_LIB)"; \ else \ + echo "=== Building cross-compilation prerequisites ==="; \ + $(MAKE) stage-jsqlite ffi-shim-symbols.list jerboa gen-embed chez-cross-arm64 rust-coreutils-linux-arm64 jerboa-native-linux-arm64 vendor-staged-libs yubikey-native-linux-arm64; \ + echo "=== Wiping stale per-arch compiled artifacts (.so/.wpo/boot) ==="; \ + $(XC_WIPE); \ echo "=== Cross-building jsh-linux-arm64 (aarch64 Linux static, JSH_FEATURES=$$features) ==="; \ JERBOA_HOME=$(JERBOA_HOME) TARGET_ARCH=arm64 JSH_FEATURES="$$features" JERBOA_NATIVE_FEATURES="$(JERBOA_NATIVE_FEATURES)" JERBOA_NATIVE_A="$(XC_NATIVE_MUSL_ARM64_LIB)" YUBIKEY_NATIVE_A="$(XC_YUBIKEY_NATIVE_MUSL_ARM64_LIB)" $(SCHEME) -q --libdirs "$(XC_LIBDIRS)" --script build-jsh-cross.ss; \ fi new file mode 100755 --- /dev/null +++ b/support/patch-extras-build.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# patch-extras-build.sh — Apply yubikey/udev patches to extras repo build config. +# Called by ensure-shell-extras from the main repo's Makefile. +set -eu + +EXTRAS_DIR="${1:-}" +if [ -z "$EXTRAS_DIR" ]; then + echo "Usage: $0 <jerboa-shell-extras-dir>" >&2 + exit 1 +fi + +# Patch .jerbuild.linux-amd64: add yubikey archive +JERBUILD_CONFIG="$EXTRAS_DIR/.jerbuild.linux-amd64" +if [ -f "$JERBUILD_CONFIG" ]; then + grep -q 'libyubikey_native' "$JERBUILD_CONFIG" 2>/dev/null || \ + perl -i -pe 's/(_jerbuild-stage\/libjerboa_fuse\.a)/$1\n "_jerbuild-stage\/libyubikey_native.a"/' "$JERBUILD_CONFIG" + perl -i -pe 's/(-ltinfo)"/$1 -ludev"/' "$JERBUILD_CONFIG" +fi + +# Patch stage-for-jerbuild-linux.sh: add yubikey staging section +STAGE_SCRIPT="$EXTRAS_DIR/support/stage-for-jerbuild-linux.sh" +if [ -f "$STAGE_SCRIPT" ]; then + grep -q 'yubikey-native' "$STAGE_SCRIPT" 2>/dev/null || \ + cat >> "$STAGE_SCRIPT" << 'PATCH_EOF' + +# ── yubikey-native Rust archive ──────────────────────────────────────── +YUBIKEY_NATIVE_DIR="${VENDOR}/jerboa-yubikey/yubikey-native" +YUBIKEY_NATIVE_AR_OUT="${STAGE}/libyubikey_native.a" +if [ -f "${YUBIKEY_NATIVE_DIR}/target/release/libyubikey_native.a" ]; then + echo "==> Staging yubikey-native archive -> ${YUBIKEY_NATIVE_AR_OUT}" + cp -f "${YUBIKEY_NATIVE_DIR}/target/release/libyubikey_native.a" "${YUBIKEY_NATIVE_AR_OUT}" +else + echo "==> yubikey-native not found; creating empty ${YUBIKEY_NATIVE_AR_OUT}" + [ -n "$(command -v ar || command -v llvm-ar || true)" ] && \ + "$(command -v ar || command -v llvm-ar)" rcs "${YUBIKEY_NATIVE_AR_OUT}" || true +fi +PATCH_EOF +fi \ No newline at end of file --- a/support/stage-for-jerbuild-linux.sh +++ b/support/stage-for-jerbuild-linux.sh @@ -87,6 +87,30 @@ find "${STAGE}/jsqlite" -type f \( -name '*.so' -o -name '*.wpo' \ # libdir entry shadows the vendor copy. patch_into "${REPO_ROOT}/patches/sed-pcre2.sls" "${STAGE}/sed/pcre2.sls" +# ── [3b/5] Use extras repo's jsh.ss if available (embeds extras commands) ── +EXTRAS_JSH="${VENDOR}/jerboa-shell-extras/jsh.ss" +EXTRAS_JSH_SRC="${VENDOR}/jerboa-shell-extras/jerboa-src/src/jsh" +if [ -f "${EXTRAS_JSH}" ]; then + echo "==> [3b/5] Using extras jsh.ss from ${EXTRAS_JSH}" + cp -f "${EXTRAS_JSH}" "${REPO_ROOT}/jsh.ss" + echo "==> [3c/5] Copying extras jsh modules from ${EXTRAS_JSH_SRC}" + for f in "${EXTRAS_JSH_SRC}"/*.ss; do + [ -f "$f" ] || continue + bn=$(basename "$f") + # Don't overwrite core modules that may already exist via jsh-src + if [ ! -f "${REPO_ROOT}/jsh-src/jsh/${bn}" ]; then + cp "$f" "${REPO_ROOT}/jsh-src/jsh/${bn}" + fi + done + echo "==> [3d/5] Re-translating jsh-src to include extras modules" + "${JERBUILD}" exec --libdirs "${RUN_LIBDIRS}" support/jerbuild.ss "${REPO_ROOT}/jsh-src" "${REPO_ROOT}/src" --force +fi +# Translate extras .ss modules to .sls if present +if [ -d "${EXTRAS_JSH_SRC}" ]; then + echo "==> [3c/5] Translating extras jsh modules from ${EXTRAS_JSH_SRC}" + "${JERBUILD}" exec --libdirs "${RUN_LIBDIRS}" support/jerbuild.ss "${EXTRAS_JSH_SRC}" "${REPO_ROOT}/src" --force +fi + # ── [4/5] Regenerate jsh-generated.ss ────────────────────────────────────── export JSH_FEATURES="${JSH_FEATURES:-}" echo "==> [4/5] Regenerating jsh-generated.ss (features='${JSH_FEATURES}')" @@ -256,4 +280,19 @@ else [ -n "${_FUSE_AR}" ] && "${_FUSE_AR}" rcs "${FUSE_AR_OUT}" || true fi +# ── yubikey-native Rust archive ──────────────────────────────────────── +YUBIKEY_NATIVE_DIR="${VENDOR}/jerboa-yubikey/yubikey-native" +YUBIKEY_NATIVE_AR_OUT="${STAGE}/libyubikey_native.a" +if [ -f "${YUBIKEY_NATIVE_DIR}/target/release/libyubikey_native.a" ]; then + echo "==> Staging yubikey-native archive -> ${YUBIKEY_NATIVE_AR_OUT}" + cp -f "${YUBIKEY_NATIVE_DIR}/target/release/libyubikey_native.a" "${YUBIKEY_NATIVE_AR_OUT}" +elif [ -f "${YUBIKEY_NATIVE_DIR}/target/${RUST_TARGET}/release/libyubikey_native.a" ]; then + echo "==> Staging yubikey-native archive -> ${YUBIKEY_NATIVE_AR_OUT}" + cp -f "${YUBIKEY_NATIVE_DIR}/target/${RUST_TARGET}/release/libyubikey_native.a" "${YUBIKEY_NATIVE_AR_OUT}" +else + echo "==> yubikey-native not found; creating empty ${YUBIKEY_NATIVE_AR_OUT}" + [ -n "$(command -v ar || command -v llvm-ar || true)" ] && \ + "$(command -v ar || command -v llvm-ar)" rcs "${YUBIKEY_NATIVE_AR_OUT}" || true +fi + echo "==> stage-for-jerbuild-linux: done"