kit_cross_verify.sh (3690B)
1 #!/usr/bin/env bash 2 # scripts/kit_cross_verify.sh — run a cross-built `kit` binary on its target via 3 # the shared exec seam (test/lib/exec_target.sh) and confirm it executes there. 4 # Called by `kit_cross.sh --verify`; usable standalone. 5 # 6 # kit_cross_verify.sh <target> <kit-binary> 7 # 8 # target a hosted token (linux-…/freebsd-…/windows-…/macos-aa64). 9 # kit-binary path to the cross-built kit[.exe] (kit_cross.sh's output). 10 # 11 # The probe runs the binary with no arguments: bare `kit` prints its top-level 12 # help banner and exits 0, which exercises load + dynamic-linker + libc init + 13 # main on the target. Pass = exit 0 and the banner appears on stdout. 14 # 15 # Per the port-infra contract, an unprovisioned/unreachable runner is an ERROR 16 # (not a skip): run `make provision TARGET=<target> [KIT_VM=1]` first. 17 18 # set -u only (no -e): exec_target.sh's runners return non-zero in normal flow 19 # and report status via the RUN_RC global, exactly as scripts/cross_test.sh 20 # drives them. Errors here are handled explicitly via die() / RUN_RC checks. 21 set -u 22 23 ROOT="$(cd "$(dirname "$0")/.." && pwd)" 24 cd "$ROOT" 25 HOSTED="$ROOT/scripts/hosted.sh" 26 27 die() { printf 'kit_cross_verify: %s\n' "$*" >&2; exit 1; } 28 29 TARGET="${1:-}"; BIN="${2:-}" 30 [ -n "$TARGET" ] && [ -n "$BIN" ] || die "usage: kit_cross_verify.sh <target> <kit-binary>" 31 [ -f "$BIN" ] || die "kit binary not found: $BIN" 32 33 os="${TARGET%%-*}" 34 case "$os" in freestanding) die "$TARGET is freestanding — kit needs an OS to run on" ;; esac 35 tag="$("$HOSTED" tag "$TARGET")" || die "bad target '$TARGET'" 36 37 # ---- exec_target caller contract (mirrors scripts/cross_test.sh) ----------- 38 have_podman=0; command -v podman >/dev/null 2>&1 && have_podman=1 39 QEMU_BIN="${QEMU_BIN:-$(command -v qemu-aarch64 2>/dev/null || true)}" 40 QEMU_RV64_BIN="${QEMU_RV64_BIN:-$(command -v qemu-riscv64 2>/dev/null || true)}" 41 have_qemu=0; [ -n "$QEMU_BIN" ] && have_qemu=1 42 case "$(uname -m 2>/dev/null)" in aarch64|arm64) is_aarch64=1 ;; *) is_aarch64=0 ;; esac 43 export have_podman QEMU_BIN QEMU_RV64_BIN have_qemu is_aarch64 44 45 # Stage the binary in its own scratch dir: the podman runner mounts the exe's 46 # directory as /work, so keep it free of the multi-MB build tree around it. 47 WORK="$ROOT/build/kit-cross/.verify/$TARGET" 48 rm -rf "$WORK"; mkdir -p "$WORK" 49 runbase="kit"; case "$os" in windows) runbase="kit.exe" ;; esac 50 cp "$BIN" "$WORK/$runbase" || die "failed to stage $BIN"; chmod +x "$WORK/$runbase" 51 EXEC_TARGET_MOUNT_ROOT="$WORK"; export EXEC_TARGET_MOUNT_ROOT 52 53 # shellcheck source=../test/lib/exec_target.sh 54 . "$ROOT/test/lib/exec_target.sh" 55 trap exec_target_teardown_all EXIT 56 57 exec_target_supported "$tag" || { 58 case "$os" in 59 freebsd|windows) die "VM not provisioned/reachable for $tag — run 'make provision TARGET=$TARGET KIT_VM=1'" ;; 60 macos) die "macOS targets only verify on a Darwin host" ;; 61 *) die "no runner for $tag here — install podman or qemu-user, or run 'make provision TARGET=$TARGET'" ;; 62 esac 63 } 64 65 exec_target_setup "$tag" || true 66 67 printf 'kit_cross_verify: running %s on %s (tag=%s)\n' "$runbase" "$TARGET" "$tag" 68 RUN_RC=127 69 exec_target_run "$tag" "$WORK/$runbase" "$WORK/out.txt" "$WORK/err.txt" 70 71 banner='freestanding C compiler toolchain' 72 if [ "${RUN_RC:-127}" -eq 0 ] && grep -q "$banner" "$WORK/out.txt" 2>/dev/null; then 73 printf 'kit_cross_verify: PASS — %s ran on %s (rc=0, banner ok)\n' "$runbase" "$TARGET" 74 exit 0 75 fi 76 77 printf 'kit_cross_verify: FAIL — %s on %s (rc=%s)\n' "$runbase" "$TARGET" "${RUN_RC:-127}" >&2 78 printf '--- stdout ---\n' >&2; tail -5 "$WORK/out.txt" 2>/dev/null >&2 || true 79 printf '--- stderr ---\n' >&2; tail -5 "$WORK/err.txt" 2>/dev/null >&2 || true 80 exit 1