#!/usr/bin/env bash # Build the kernel's ABI test programs ("fixtures") from the pinned kernel # source (out/kernel-src/user, exported by build-kernel.sh), with exactly the # commands the kernel's build.rs uses. Under boot contract v1 the image # carries them in /bin because the self-test runs them; they are *not* part # of Foundry OS and their source stays in the kernel repo. # # Usage: scripts/build-fixtures.sh KERNEL_SRC OUT_DIR "rust names" "c names" "musl name:kind ..." set -euo pipefail SRC=$(realpath "$1")/user OUT=$(realpath -m "$2") RUST=$3 C=$4 MUSL=$5 mkdir -p "$OUT" RUSTC=${RUSTC:-rustc} # Use the kernel's toolchain (rust-toolchain.toml in KERNEL_SRC): run from there. cd "$SRC/.." for p in $RUST; do "$RUSTC" --edition 2024 --target x86_64-unknown-none \ -C panic=abort -C opt-level=2 -C debuginfo=0 -C strip=debuginfo \ -C relocation-model=static -C code-model=large \ -C "link-arg=-T$SRC/link.ld" -o "$OUT/$p" "$SRC/$p.rs" done # No libc at all: raw Linux syscalls, an ordinary static ET_EXEC at the # usual 0x400000 (user space since Rustbelt 0.20.0). for p in $C; do ${CC:-cc} -O2 -static -nostdlib -ffreestanding -fno-stack-protector \ -no-pie -Wall -Wextra \ -Wl,--build-id=none -z noexecstack \ -o "$OUT/$p" "$SRC/$p.c" done # musl (Debian's musl-tools), always the stock recipes: "pie" is # `musl-gcc -static-pie`, "exec" is plain `musl-gcc -static` (an ET_EXEC at # 0x400000; Rustbelt runs that since 0.20.0), "dyn" must be refused. # Entries are name:kind[:source] (source file in user/, default = name). for entry in $MUSL; do IFS=: read -r p kind src <<< "$entry" src=$SRC/${src:-$p}.c common=(-O2 -Wall -Wextra -pthread -Wl,--build-id=none) case $kind in pie) musl-gcc "${common[@]}" -static-pie "$src" -o "$OUT/$p" ;; dyn) musl-gcc "${common[@]}" -fPIE -pie "$src" -o "$OUT/$p" ;; exec) musl-gcc "${common[@]}" -static "$src" -o "$OUT/$p" ;; *) echo "unknown musl kind $kind for $p"; exit 1 ;; esac done echo "[fixtures] $(ls "$OUT" | wc -l) programs in $OUT"