#!/usr/bin/env bash # Proves a toolchain can make a runnable linux-arm64 binary: builds the # hello-world in scripts/smoke/, checks it is aarch64 and static (or # libc-only), and runs it under qemu. Prints ": ok" on success. # scripts/smoke.sh set -euo pipefail here=$(cd "$(dirname "$0")" && pwd) source "$here/env.sh" lang=$1 src="$here/smoke/$lang" out=$(mktemp -d -p "${TMPDIR:-$HOME/.cache}") trap 'rm -rf "$out"' EXIT bin="$out/smoke" case $lang in go) (cd "$src" && CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o "$bin" .) ;; rust) (cd "$src" && CARGO_TARGET_DIR="$out/target" cargo zigbuild -q --release --target aarch64-unknown-linux-musl && cp "$out/target/aarch64-unknown-linux-musl/release/smoke" "$bin") ;; zig) (cd "$out" && zig build-exe -target aarch64-linux-musl -O ReleaseSmall -femit-bin="$bin" "$src/main.zig") ;; swift) (cd "$src" && swift build -q -c release --swift-sdk aarch64-swift-linux-musl --scratch-path "$out/build" && cp "$out/build/aarch64-swift-linux-musl/release/smoke" "$bin") ;; ocaml) cp "$src/main.ml" "$out/" && (cd "$out" && "$here/arm64.sh" ocamlfind ocamlopt -package unix -linkpkg -ccopt -static main.ml -o smoke) ;; haskell) cp "$src/Main.hs" "$out/" && (cd "$out" && "$here/arm64.sh" ghc -O -static -optl-static -optl-pthread Main.hs -o smoke >/dev/null) ;; mojo) cp "$src/main.mojo" "$out/" && (cd "$out" && "$here/arm64.sh" /root/.pixi/bin/mojo build main.mojo -o smoke 2>/dev/null) ;; spinel) "$here/smoke-spinel.sh" "$src/main.rb" "$bin" ;; nim) (cd "$out" && nim c --hints:off -d:release --cpu:arm64 --os:linux --cc:clang \ --clang.exe="$here/zigcc-aarch64-musl" --clang.linkerexe="$here/zigcc-aarch64-musl" \ --passL:-static --nimcache:"$out/cache" -o:"$bin" "$src/main.nim" >/dev/null) ;; *) echo "unknown language $lang" >&2; exit 2 ;; esac desc=$(file -b "$bin") echo "$lang: $desc" | cut -c1-160 case $desc in *aarch64*) ;; *) echo "$lang: not an aarch64 binary" >&2; exit 1 ;; esac case $desc in *"statically linked"*|*"static-pie"*) ;; *) extra=$(readelf -d "$bin" | sed -n 's/.*(NEEDED).*\[\(.*\)\]/\1/p' | grep -Ev '^(libc|libm|libpthread|libdl|librt|ld-linux-aarch64)\.so' || true) [ -z "$extra" ] || { echo "$lang: needs shared libraries beyond libc: $extra" >&2; exit 1; } ;; esac got=$(qemu-aarch64-static -L "${BAKEOFF_TOOLCHAINS:-$HOME/.local/share/bakeoff-toolchains}/arm64root" "$bin") [ "$got" = ok ] || { echo "$lang: printed '$got', want ok" >&2; exit 1; } echo "$lang: ok"