kit

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

run.sh (6030B)


      1 #!/usr/bin/env bash
      2 # test/rt/run.sh — runtime tests for rt/include headers and libkit_rt.a, on
      3 # the shared corpus harness (test/lib/kit_corpus.sh).
      4 #
      5 # Each case (test/rt/cases/*.c) is compiled with `kit cc` against rt/include,
      6 # linked with the freestanding test _start and the matching libkit_rt.a, then
      7 # executed on the target when a runner exists. A correct run exits 42.
      8 #
      9 # This is a single-lane (R), no-opt corpus swept across one tuple per arch.
     10 # Arch selection: KIT_RT_RUNTIME_ARCHES (default "aa64 x64 rv64"). Each arch
     11 # maps to an <arch>-linux exec_target tag and a clang `--target=` triple; the
     12 # per-arch rt archive / clang start.o / extra clang flags are resolved
     13 # LANE-LOCAL in kit_lane_R (no shared sysroot driver), and every artifact is
     14 # written under $KIT_WORK so the lane is parallel-safe by construction.
     15 #
     16 # Skip conditions (each a SKIP, not a failure):
     17 #   - libkit_rt.a for the arch missing
     18 #   - no execution runner for the arch (podman/qemu/native)
     19 #   - clang cannot build the freestanding start.o for the triple
     20 # Set KIT_TEST_ALLOW_SKIP=1 to let the run exit 0 with skips.
     21 
     22 set -u
     23 
     24 ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
     25 CASES_DIR="$ROOT/test/rt/cases"
     26 BUILD_DIR="$ROOT/build/test/rt-runtime"
     27 KIT="$ROOT/build/kit"
     28 LINK_EXE_RUNNER="$ROOT/build/test/link-exe-runner"
     29 START_SRC="$ROOT/test/link/harness/start.c"
     30 
     31 export KIT_LIB_DIR="$ROOT/test/lib"
     32 # shellcheck source=../lib/kit_corpus.sh
     33 . "$ROOT/test/lib/kit_corpus.sh"
     34 
     35 mkdir -p "$BUILD_DIR"
     36 
     37 if [ ! -x "$KIT" ]; then
     38   printf 'kit driver missing at %s -- run `make bin` first\n' "$KIT" >&2
     39   exit 2
     40 fi
     41 if [ ! -x "$LINK_EXE_RUNNER" ]; then
     42   printf 'link-exe-runner missing at %s -- run `make test-rt-runtime` from make\n' \
     43     "$LINK_EXE_RUNNER" >&2
     44   exit 2
     45 fi
     46 
     47 # exec_target wiring. The aarch64 helper expects these names regardless of
     48 # target arch — they describe host detection rather than the target.
     49 have_qemu=0
     50 QEMU_BIN="$(command -v qemu-aarch64-static 2>/dev/null || command -v qemu-aarch64 2>/dev/null || true)"
     51 [ -n "$QEMU_BIN" ] && have_qemu=1
     52 have_podman=0
     53 command -v podman >/dev/null 2>&1 && have_podman=1
     54 arch_raw="$(uname -m 2>/dev/null || true)"
     55 is_aarch64=0
     56 if [ "$(uname -s 2>/dev/null)" = "Linux" ]; then
     57   { [ "$arch_raw" = "aarch64" ] || [ "$arch_raw" = "arm64" ]; } && is_aarch64=1
     58 fi
     59 export have_qemu QEMU_BIN have_podman is_aarch64
     60 
     61 EXEC_TARGET_MOUNT_ROOT="$BUILD_DIR"
     62 export EXEC_TARGET_MOUNT_ROOT
     63 # shellcheck source=../lib/exec_target.sh
     64 . "$ROOT/test/lib/exec_target.sh"
     65 
     66 # ---- per-arch wiring (LANE-LOCAL) ------------------------------------------
     67 
     68 arch_triple() {
     69   case "$1" in
     70     aa64) echo "aarch64-linux-gnu" ;;
     71     x64)  echo "x86_64-linux-gnu" ;;
     72     rv64) echo "riscv64-linux-gnu" ;;
     73     *) return 1 ;;
     74   esac
     75 }
     76 
     77 rt_archive() {
     78   case "$1" in
     79     aa64) echo "$ROOT/build/rt/aarch64-linux/libkit_rt.a" ;;
     80     x64)  echo "$ROOT/build/rt/x86_64-linux/libkit_rt.a" ;;
     81     rv64) echo "$ROOT/build/rt/riscv64-linux/libkit_rt.a" ;;
     82     *) return 1 ;;
     83   esac
     84 }
     85 
     86 clang_extra_flags() {
     87   case "$1" in
     88     rv64) echo "-march=rv64gc" ;;
     89     *) echo "" ;;
     90   esac
     91 }
     92 
     93 # ---- lane R: compile (kit cc) -> link (link-exe-runner) -> exec -----------
     94 # Synchronous exec via exec_target_run (matches the original per-case flow).
     95 # KIT_ARCH is the corpus tuple's arch ("aa64"/"x64"/"rv64"); KIT_OBJ is "linux".
     96 kit_lane_R() {
     97   local arch="$KIT_ARCH" name="$KIT_ARCH/$KIT_NAME"
     98   local triple rtlib start_obj extra
     99   triple="$(arch_triple "$arch")" || { kit_fail "$name" "unknown arch '$arch'"; return; }
    100   rtlib="$(rt_archive "$arch")"
    101   extra="$(clang_extra_flags "$arch")"
    102   start_obj="$KIT_WORK/start.o"
    103 
    104   if [ ! -f "$rtlib" ]; then
    105     kit_skip "$name" "runtime archive missing at $rtlib"; return
    106   fi
    107   if ! exec_target_supported "$arch"; then
    108     kit_skip "$name" "no execution runner"; return
    109   fi
    110   if ! clang --target="$triple" $extra -O1 -ffreestanding -fno-stack-protector \
    111       -fno-PIC -fno-pie -c "$START_SRC" -o "$start_obj" \
    112       >"$KIT_WORK/start.out" 2>"$KIT_WORK/start.err"; then
    113     kit_skip "$name" "clang cannot build start.o for $triple"; return
    114   fi
    115 
    116   # Opt axis: KIT_OPT is the corpus opt level ("0"/"1"/…); "-" is the
    117   # no-axis sentinel. Pass -O<level> only for a real level so the FP-chain
    118   # walk is exercised against both unoptimized and optimized callers.
    119   local optflag=""
    120   case "$KIT_OPT" in 0|1|2|3|s|z) optflag="-O$KIT_OPT" ;; esac
    121 
    122   local obj="$KIT_WORK/$KIT_BASE.o"
    123   local exe="$KIT_WORK/$KIT_BASE.exe"
    124   if ! "$KIT" cc -target "$triple" $optflag -Werror -c "$KIT_SRC" -o "$obj" \
    125       >"$KIT_WORK/cc.out" 2>"$KIT_WORK/cc.err"; then
    126     kit_fail "$name" "compile (see $KIT_WORK/cc.err)"; return
    127   fi
    128 
    129   if ! KIT_TEST_ARCH="$arch" "$LINK_EXE_RUNNER" -o "$exe" "$obj" "$start_obj" \
    130       --archive "$rtlib" >"$KIT_WORK/link.out" 2>"$KIT_WORK/link.err"; then
    131     kit_fail "$name" "link (see $KIT_WORK/link.err)"; return
    132   fi
    133 
    134   exec_target_run "$arch" "$exe" "$KIT_WORK/run.out" "$KIT_WORK/run.err"
    135   if [ "$RUN_RC" -eq 42 ]; then
    136     kit_pass "$name"
    137   else
    138     kit_fail "$name" "run (expected 42 got $RUN_RC; see $KIT_WORK/run.err)"
    139   fi
    140 }
    141 
    142 # ---- drive the corpus ------------------------------------------------------
    143 # One tuple per requested arch (<arch>-linux). No opt axis; single lane R.
    144 ARCHES="${KIT_RT_RUNTIME_ARCHES:-aa64 x64 rv64}"
    145 TUPLES=
    146 for arch in $ARCHES; do
    147   case "$arch" in
    148     aa64|x64|rv64) TUPLES="$TUPLES $arch-linux" ;;
    149     *) kit_fail "unknown arch '$arch'" ;;
    150   esac
    151 done
    152 
    153 # Opt axis: sweep O0 and O1 so the runtime cases (notably the FP-chain
    154 # backtrace walk) are exercised against both unoptimized and optimized
    155 # callers. Override with KIT_RT_OPT_LEVELS (e.g. "0" for a faster smoke).
    156 KIT_LABEL=test-rt-runtime KIT_BUILD_DIR="$BUILD_DIR" \
    157   KIT_CORPUS_GLOBS="$CASES_DIR/*.c" KIT_CORPUS_EXT=c KIT_SIDECAR_DIR="$CASES_DIR" \
    158   KIT_LANES="R" KIT_OPT_LEVELS="${KIT_RT_OPT_LEVELS:-0 1}" KIT_TUPLES="$TUPLES" \
    159   KIT_TARGETS_EXT="" \
    160   KIT_PARALLELIZABLE="${KIT_RT_PARALLEL:-1}" kit_corpus_run
    161 
    162 kit_summary test-rt-runtime
    163 kit_exit