kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit e588f2ff4cc4f95d7eab3cfd1847b490eb157c5f
parent c89c279bfba06ba19c63e497e07187f08da8ab1f
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Wed, 17 Jun 2026 15:45:52 -0700

test: test-t1-cross for cross-compile and cross-link

Diffstat:
Mmk/test.mk | 4++++
Mtest/TESTMAP.md | 1+
Mtest/tier1/README.md | 4++++
Atest/tier1/cross/README.md | 24++++++++++++++++++++++++
Atest/tier1/cross/run.sh | 230+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtest/tier1/run_logged.sh | 6++++++
6 files changed, 269 insertions(+), 0 deletions(-)

diff --git a/mk/test.mk b/mk/test.mk @@ -214,6 +214,7 @@ TIER1_TEST_TARGETS = \ test-t1-asm-disas \ test-t1-obj \ test-t1-link-jit \ + test-t1-cross \ test-t1-rt \ test-t1-debug \ test-t1-emu-interp \ @@ -276,6 +277,9 @@ test-t1-link-jit: $(LINK_EXE_RUNNER) @$(T1_LOG) link test/tier1/objlink/link.sh @$(T1_LOG) jit-relax $(MAKE) --no-print-directory test-link-jit-tls-relax +test-t1-cross: bin + @$(T1_LOG) cross env KIT=$(abspath $(BIN)) test/tier1/cross/run.sh + test-t1-rt: @$(T1_LOG) rt test/tier1/system/runtime-headers.sh diff --git a/test/TESTMAP.md b/test/TESTMAP.md @@ -13,6 +13,7 @@ area you changed. | `src/asm/**`, `driver/cmd/as.c`, `driver/cmd/disas.c` | `make test-t1-asm-disas` | `make test-asm` | | `src/obj/**`, object format readers/writers | `make test-t1-obj` | `make test-elf test-macho test-coff` | | `src/link/**`, JIT image mapping | `make test-t1-link-jit` | `make test-link` | +| cross hosted profiles, sysroot resolution, target triples | `make test-t1-cross` | `make test-cross TARGET=<selector> DEPTH=smoke` | | `rt/**` | `make test-t1-rt` | `make test-rt-runtime test-rt-backtrace` | | `src/debug/**`, `src/dbg/**` | `make test-t1-debug` | `make test-debug test-dwarf test-dbg` | | `src/emu/**`, `src/interp/**` | `make test-t1-emu-interp` | `make test-emu test-emu-unit test-interp` | diff --git a/test/tier1/README.md b/test/tier1/README.md @@ -13,5 +13,9 @@ Rules: - If a Tier 1 sentinel fails, run the matching focused suite from `test/TESTMAP.md`. +The cross sentinel is build/link-only. It covers the supported cross matrix and +reports missing provisioned sysroots or SDKs as SKIP with exit 0. Narrow it with +`T1_CROSS_TARGETS=<selector>` when needed. + `make test` runs Tier 1 in parallel. The previous broad default is available as `make test-full`. diff --git a/test/tier1/cross/README.md b/test/tier1/cross/README.md @@ -0,0 +1,24 @@ +# Cross Tier 1 + +`run.sh` is the Tier 1 cross-compile/link sentinel. It covers the portability +support set at build/link depth only; it does not execute target artifacts. + +Missing provisioned sysroots or SDKs are reported as `SKIP` and exit 0. Real +compile/link failures are `FAIL`. + +Covered lanes: + +- `linux-{glibc,musl}-{aa64,x64,rv64}`; musl runs both `static` and `dynamic` + link modes. +- `freebsd-{aa64,x64,rv64}`. +- `windows-{aa64,x64}`. +- `android-aa64` as a shared `NativeActivity` build. +- `macos-{aa64,x64}` when the macOS SDK is available on Darwin. +- `ios-aa64`, `ios-sim-{aa64,x64}` when the relevant Xcode SDK is available. +- `freestanding-{aa64,x64,rv64,rv32,arm32}` with compile plus `kit ld`. + +Provision hosted sysroots with: + +```sh +make provision TARGET=<selector> +``` diff --git a/test/tier1/cross/run.sh b/test/tier1/cross/run.sh @@ -0,0 +1,230 @@ +#!/usr/bin/env bash +set -u + +ROOT="$(cd "$(dirname "$0")/../../.." && pwd)" +KIT="${KIT:-$ROOT/build/kit}" +HOSTED="$ROOT/scripts/hosted.sh" +CASES="$ROOT/test/cross/cases" +WORK="$ROOT/build/test/tier1/cross" +SELECTOR="${T1_CROSS_TARGETS:-all}" + +mkdir -p "$WORK" + +. "$ROOT/test/lib/kit_sh_report.sh" +kit_report_init +KIT_SKIP_IS_FAILURE=0 + +if [ ! -x "$KIT" ]; then + kit_fail "cross/setup" "kit not built at $KIT" + kit_summary test-t1-cross + kit_exit +fi + +match_selector() { + local lane="$1" sel item + sel="$(printf '%s' "$SELECTOR" | tr , ' ')" + [ "$sel" = all ] && return 0 + for item in $sel; do + case "$lane" in + "$item"|"$item"-*|*-"$item") return 0 ;; + esac + case "$item:$lane" in + linux:"linux-"*|linux-glibc:"linux-glibc-"*|linux-musl:"linux-musl-"*) return 0 ;; + freebsd:"freebsd-"*|windows:"windows-"*|android:"android-"*) return 0 ;; + macos:"macos-"*|ios:"ios-"*|freestanding:"freestanding-"*) return 0 ;; + esac + done + return 1 +} + +hosted_path() { + "$HOSTED" path "$1" 2>/dev/null || true +} + +hosted_triple() { + "$HOSTED" triple "$1" 2>/dev/null || true +} + +hosted_needs_sysroot() { + case "$1" in + linux-*|freebsd-*|windows-*|android-*) return 0 ;; + *) return 1 ;; + esac +} + +mode_flag() { + case "$1" in static) printf '%s\n' -static ;; *) printf '\n' ;; esac +} + +run_cmd() { + local label="$1" log="$2" + shift 2 + if "$@" >"$log" 2>&1; then + return 0 + fi + kit_fail "$label" "see $log" + return 1 +} + +hosted_lane() { + local token="$1" mode="$2" label="$1" sysroot triple dir obj exe flag + [ "$mode" != default ] && label="$label:$mode" + match_selector "$token" || return 0 + + triple="$(hosted_triple "$token")" + if [ -z "$triple" ]; then + kit_skip "$label" "not in hosted support set" + return 0 + fi + + if hosted_needs_sysroot "$token"; then + sysroot="$(hosted_path "$token")" + if [ -z "$sysroot" ] || [ ! -d "$sysroot" ]; then + kit_skip "$label" "sysroot not provisioned; run: make provision TARGET=$token" + return 0 + fi + fi + + case "$token" in + macos-*) + if [ "$(uname -s 2>/dev/null)" != Darwin ]; then + kit_skip "$label" "macOS cross-link requires Darwin SDK host" + return 0 + fi + if ! xcrun --sdk macosx --show-sdk-path >/dev/null 2>&1; then + kit_skip "$label" "macOS SDK unavailable" + return 0 + fi ;; + esac + + dir="$WORK/$label" + mkdir -p "$dir" + obj="$dir/exit.o" + exe="$dir/exit" + case "$token" in windows-*) exe="$exe.exe" ;; esac + flag="$(mode_flag "$mode")" + + run_cmd "$label:cc" "$dir/cc.log" \ + "$HOSTED" cc "$token" -O1 -c "$CASES/exit.c" -o "$obj" || return 0 + # shellcheck disable=SC2086 + run_cmd "$label:ld" "$dir/ld.log" \ + "$HOSTED" cc "$token" $flag "$obj" -o "$exe" || return 0 + + if [ -s "$exe" ]; then + kit_pass "$label" + else + kit_fail "$label" "linked artifact missing" + fi +} + +android_lane() { + local token=android-aa64 label=android-aa64 sysroot dir obj so + match_selector "$token" || return 0 + sysroot="$(hosted_path "$token")" + if [ -z "$sysroot" ] || [ ! -d "$sysroot" ]; then + kit_skip "$label" "Android NDK sysroot not provisioned; run: make provision TARGET=$token" + return 0 + fi + dir="$WORK/$label" + mkdir -p "$dir" + obj="$dir/native_activity.o" + so="$dir/libkit_native_activity.so" + run_cmd "$label:cc" "$dir/cc.log" \ + "$HOSTED" cc "$token" -O1 -fPIC -c "$CASES/native_activity.c" -o "$obj" || return 0 + run_cmd "$label:ld" "$dir/ld.log" \ + "$HOSTED" cc "$token" -shared "$obj" -landroid -o "$so" || return 0 + if [ -s "$so" ]; then kit_pass "$label"; else kit_fail "$label" "shared object missing"; fi +} + +apple_sdk_path() { + local sdk="$1" + xcrun --sdk "$sdk" --show-sdk-path 2>/dev/null || true +} + +apple_lane() { + local lane="$1" triple="$2" sdk_name="$3" label="$1" sdk dir obj exe + match_selector "$lane" || return 0 + if [ "$(uname -s 2>/dev/null)" != Darwin ]; then + kit_skip "$label" "$sdk_name SDK requires Darwin host" + return 0 + fi + sdk="$(apple_sdk_path "$sdk_name")" + if [ -z "$sdk" ] || [ ! -d "$sdk" ]; then + kit_skip "$label" "$sdk_name SDK unavailable" + return 0 + fi + dir="$WORK/$label" + mkdir -p "$dir" + obj="$dir/exit.o" + exe="$dir/exit" + run_cmd "$label:cc" "$dir/cc.log" \ + "$KIT" cc -target "$triple" --sysroot "$sdk" -O1 -c "$CASES/exit.c" -o "$obj" || return 0 + run_cmd "$label:ld" "$dir/ld.log" \ + "$KIT" cc -target "$triple" --sysroot "$sdk" "$obj" -lc -o "$exe" || return 0 + if [ -s "$exe" ]; then kit_pass "$label"; else kit_fail "$label" "linked artifact missing"; fi +} + +freestanding_triple() { + case "$1" in + aa64) echo aarch64-none-elf ;; + x64) echo x86_64-none-elf ;; + rv64) echo riscv64-none-elf ;; + rv32) echo riscv32-none-elf ;; + arm32) echo arm-none-eabi ;; + *) return 1 ;; + esac +} + +freestanding_extra_flags() { + case "$1" in + rv32) printf '%s\n' "-march=rv32imafc_zicsr_zifencei -mabi=ilp32f" ;; + arm32) printf '%s\n' "-mcpu=cortex-m3 -mfloat-abi=soft" ;; + *) printf '\n' ;; + esac +} + +freestanding_lane() { + local arch="$1" token="freestanding-$1" triple dir obj exe extra + match_selector "$token" || return 0 + triple="$(freestanding_triple "$arch")" || { + kit_skip "$token" "unsupported freestanding arch" + return 0 + } + dir="$WORK/$token" + mkdir -p "$dir" + obj="$dir/exit.o" + exe="$dir/exit.elf" + extra="$(freestanding_extra_flags "$arch")" + # shellcheck disable=SC2086 + run_cmd "$token:cc" "$dir/cc.log" \ + "$KIT" cc -target "$triple" $extra -O1 -ffreestanding -nostdlib \ + -c "$CASES/exit.c" -o "$obj" || return 0 + run_cmd "$token:ld" "$dir/ld.log" \ + "$KIT" ld -e main -o "$exe" "$obj" || return 0 + if [ -s "$exe" ]; then kit_pass "$token"; else kit_fail "$token" "linked artifact missing"; fi +} + +for arch in aa64 x64 rv64; do + hosted_lane "linux-glibc-$arch" default + hosted_lane "linux-musl-$arch" static + hosted_lane "linux-musl-$arch" dynamic + hosted_lane "freebsd-$arch" static +done + +for arch in aa64 x64; do + hosted_lane "windows-$arch" default + hosted_lane "macos-$arch" default +done + +android_lane + +apple_lane ios-aa64 arm64-apple-ios iphoneos +apple_lane ios-sim-aa64 arm64-apple-ios-simulator iphonesimulator +apple_lane ios-sim-x64 x86_64-apple-ios-simulator iphonesimulator + +for arch in aa64 x64 rv64 rv32 arm32; do + freestanding_lane "$arch" +done + +kit_summary test-t1-cross +kit_exit diff --git a/test/tier1/run_logged.sh b/test/tier1/run_logged.sh @@ -21,4 +21,10 @@ if [ "$rc" -ne 0 ]; then tail -100 "$log" >&2 || true exit "$rc" fi +skips="$(sed -n 's/^[^:][^:]*: skipped: //p' "$log" | tr '\n' ' ' | sed -e 's/[[:space:]][[:space:]]*/ /g' -e 's/^ //' -e 's/ $//')" +if [ -n "$skips" ]; then + nskip="$(printf '%s\n' "$skips" | wc -w | tr -d '[:space:]')" + printf 'T1 %-18s OK (%s skip: %s)\n' "$label" "$nskip" "$skips" + exit 0 +fi printf 'T1 %-18s OK\n' "$label"