kit

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

run.sh (12166B)


      1 #!/usr/bin/env bash
      2 set -u
      3 
      4 ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
      5 KIT="${KIT:-$ROOT/build/kit}"
      6 HOSTED="$ROOT/scripts/hosted.sh"
      7 CASES="$ROOT/test/cross/cases"
      8 KITCHEN="$ROOT/test/tier1/kitchen/cross"
      9 WORK="$ROOT/build/test/tier1/cross"
     10 SELECTOR="${T1_CROSS_TARGETS:-all}"
     11 PARALLEL_DIR="$WORK/.parallel"
     12 
     13 mkdir -p "$WORK" "$PARALLEL_DIR"
     14 
     15 . "$ROOT/test/lib/kit_sh_report.sh"
     16 . "$ROOT/test/tier1/timing.sh"
     17 kit_report_init
     18 KIT_SKIP_IS_FAILURE=1
     19 
     20 if [ ! -x "$KIT" ]; then
     21   kit_fail "cross/setup" "kit not built at $KIT"
     22   kit_summary test-t1-cross
     23   kit_exit
     24 fi
     25 
     26 match_selector() {
     27   local lane="$1" sel item
     28   sel="$(printf '%s' "$SELECTOR" | tr , ' ')"
     29   [ "$sel" = all ] && return 0
     30   for item in $sel; do
     31     case "$lane" in
     32       "$item"|"$item"-*|*-"$item") return 0 ;;
     33     esac
     34     case "$item:$lane" in
     35       linux:"linux-"*|linux-glibc:"linux-glibc-"*|linux-musl:"linux-musl-"*) return 0 ;;
     36       freebsd:"freebsd-"*|windows:"windows-"*|android:"android-"*) return 0 ;;
     37       macos:"macos-"*|ios:"ios-"*|freestanding:"freestanding-"*) return 0 ;;
     38     esac
     39   done
     40   return 1
     41 }
     42 
     43 hosted_path() {
     44   "$HOSTED" path "$1" 2>/dev/null || true
     45 }
     46 
     47 hosted_triple() {
     48   "$HOSTED" triple "$1" 2>/dev/null || true
     49 }
     50 
     51 hosted_needs_sysroot() {
     52   case "$1" in
     53     linux-*|freebsd-*|windows-*|android-*) return 0 ;;
     54     *) return 1 ;;
     55   esac
     56 }
     57 
     58 mode_flag() {
     59   case "$1" in static) printf '%s\n' -static ;; *) printf '\n' ;; esac
     60 }
     61 
     62 run_cmd() {
     63   local label="$1" log="$2"
     64   shift 2
     65   local start_ms dur_ms
     66   start_ms=$(t1_now_ms)
     67   if "$@" >"$log" 2>&1; then
     68     if t1_slow_timing_enabled; then
     69       dur_ms=$(t1_elapsed_ms "$start_ms" "$(t1_now_ms)")
     70       printf '    ok: %s (%sms)\n' "$label" "$dur_ms"
     71     else
     72       printf '    ok: %s\n' "$label"
     73     fi
     74     return 0
     75   fi
     76   kit_fail "$label" "see $log"
     77   if t1_slow_timing_enabled; then
     78     dur_ms=$(t1_elapsed_ms "$start_ms" "$(t1_now_ms)")
     79     printf '    failed: %s (%sms)\n' "$label" "$dur_ms"
     80   else
     81     printf '    failed: %s\n' "$label"
     82   fi
     83   return 1
     84 }
     85 
     86 hosted_lane() {
     87   local token="$1" mode="$2" label="$1" sysroot triple dir obj exe flag
     88   [ "$mode" != default ] && label="$label:$mode"
     89   match_selector "$token" || return 0
     90 
     91   triple="$(hosted_triple "$token")"
     92   if [ -z "$triple" ]; then
     93     kit_fail "$label" "not in hosted support set"
     94     return 0
     95   fi
     96 
     97   if hosted_needs_sysroot "$token"; then
     98     sysroot="$(hosted_path "$token")"
     99     if [ -z "$sysroot" ] || [ ! -d "$sysroot" ]; then
    100       kit_skip "$label" "sysroot not provisioned; run: make provision TARGET=$token"
    101       return 0
    102     fi
    103   fi
    104 
    105   case "$token" in
    106     macos-*)
    107       if [ "$(uname -s 2>/dev/null)" != Darwin ]; then
    108         kit_skip "$label" "macOS cross-link requires Darwin SDK host"
    109         return 0
    110       fi
    111       if ! xcrun --sdk macosx --show-sdk-path >/dev/null 2>&1; then
    112         kit_skip "$label" "macOS SDK unavailable"
    113         return 0
    114       fi ;;
    115   esac
    116 
    117   dir="$WORK/$label"
    118   mkdir -p "$dir"
    119   obj="$dir/exit.o"
    120   exe="$dir/exit"
    121   case "$token" in windows-*) exe="$exe.exe" ;; esac
    122   flag="$(mode_flag "$mode")"
    123 
    124   run_cmd "$label:cc" "$dir/cc.log" \
    125     "$HOSTED" cc "$token" -O1 -c "$CASES/exit.c" -o "$obj" || return 0
    126   # shellcheck disable=SC2086
    127   run_cmd "$label:ld" "$dir/ld.log" \
    128     "$HOSTED" cc "$token" $flag "$obj" -o "$exe" || return 0
    129 
    130   if [ -s "$exe" ]; then
    131     kit_pass "$label"
    132   else
    133     kit_fail "$label" "linked artifact missing"
    134   fi
    135 }
    136 
    137 android_api_lane() {
    138   local sysroot="$1" api="$2" label="android-aa64:api$2" triple dir pp obj so
    139   local readelf elf_header dynsym
    140   triple="aarch64-linux-android$api"
    141   dir="$WORK/$label"
    142   mkdir -p "$dir"
    143   pp="$dir/native_activity.i"
    144   obj="$dir/native_activity.o"
    145   so="$dir/libkit_native_activity.so"
    146   readelf="$(dirname "$sysroot")/bin/llvm-readelf"
    147   elf_header="$dir/readelf-header.log"
    148   dynsym="$dir/readelf-dynsym.log"
    149   run_cmd "$label:cpp" "$dir/cpp.log" \
    150     "$KIT" cpp -target "$triple" --sysroot "$sysroot" \
    151     -DKIT_EXPECT_ANDROID_API="$api" "$CASES/native_activity.c" -o "$pp" || return 0
    152   run_cmd "$label:cc" "$dir/cc.log" \
    153     "$KIT" cc -target "$triple" --sysroot "$sysroot" -O1 -fPIC \
    154     -DKIT_EXPECT_ANDROID_API="$api" -c "$CASES/native_activity.c" -o "$obj" || return 0
    155   run_cmd "$label:ld" "$dir/ld.log" \
    156     "$KIT" cc -target "$triple" --sysroot "$sysroot" -shared \
    157     "$obj" -landroid -o "$so" || return 0
    158   if [ ! -x "$readelf" ]; then
    159     kit_fail "$label:readelf" "NDK llvm-readelf missing at $readelf"
    160     return 0
    161   fi
    162   run_cmd "$label:elf-header" "$elf_header" \
    163     "$readelf" -h "$so" || return 0
    164   run_cmd "$label:dynsym" "$dynsym" \
    165     "$readelf" --dyn-syms --wide "$so" || return 0
    166   if [ -s "$pp" ] && [ -s "$so" ] &&
    167      grep -Eq 'Type:[[:space:]]+DYN[[:space:]]' "$elf_header" &&
    168      grep -Eq 'Machine:[[:space:]]+AArch64$' "$elf_header" &&
    169      grep -Eq 'FUNC[[:space:]]+GLOBAL[[:space:]]+DEFAULT[[:space:]]+[0-9]+[[:space:]]+ANativeActivity_onCreate$' "$dynsym"; then
    170     kit_pass "$label"
    171   else
    172     kit_fail "$label" "expected AArch64 ET_DYN export missing; see $elf_header and $dynsym"
    173   fi
    174 }
    175 
    176 android_lane() {
    177   local token=android-aa64 label=android-aa64 sysroot
    178   match_selector "$token" || return 0
    179   sysroot="$(hosted_path "$token")"
    180   if [ -z "$sysroot" ] || [ ! -d "$sysroot" ]; then
    181     kit_skip "$label" "Android NDK sysroot not provisioned; run: make provision TARGET=$token"
    182     return 0
    183   fi
    184   android_api_lane "$sysroot" 21
    185   android_api_lane "$sysroot" 35
    186   android_shared_lane "$sysroot"
    187 }
    188 
    189 android_shared_lane() {
    190   local sysroot="$1" label=android-aa64:shared dir dep_obj dep_so user_obj user_so
    191   dir="$WORK/android-aa64-shared"
    192   mkdir -p "$dir"
    193   dep_obj="$dir/dep.o"
    194   dep_so="$dir/libt1dep.so"
    195   user_obj="$dir/user.o"
    196   user_so="$dir/libt1user.so"
    197   : "$sysroot"
    198   run_cmd "$label:dep-cc" "$dir/dep-cc.log" \
    199     "$HOSTED" cc android-aa64 -O1 -fPIC -c "$KITCHEN/shared_dep.c" -o "$dep_obj" || return 0
    200   run_cmd "$label:dep-so" "$dir/dep-so.log" \
    201     "$HOSTED" cc android-aa64 -shared "$dep_obj" -o "$dep_so" || return 0
    202   run_cmd "$label:user-cc" "$dir/user-cc.log" \
    203     "$HOSTED" cc android-aa64 -O1 -fPIC -c "$KITCHEN/shared_main.c" -o "$user_obj" || return 0
    204   run_cmd "$label:user-so" "$dir/user-so.log" \
    205     "$HOSTED" cc android-aa64 -shared "$user_obj" -L "$dir" -lt1dep -o "$user_so" || return 0
    206   if [ -s "$dep_so" ] && [ -s "$user_so" ]; then kit_pass "$label"; else kit_fail "$label" "shared object missing"; fi
    207 }
    208 
    209 linux_shared_lane() {
    210   local token="$1" label="$1:shared" sysroot dir dep_obj dep_so main_obj exe
    211   match_selector "$token" || return 0
    212   sysroot="$(hosted_path "$token")"
    213   if [ -z "$sysroot" ] || [ ! -d "$sysroot" ]; then
    214     kit_skip "$label" "sysroot not provisioned; run: make provision TARGET=$token"
    215     return 0
    216   fi
    217   dir="$WORK/$token-shared"
    218   mkdir -p "$dir"
    219   dep_obj="$dir/dep.o"
    220   dep_so="$dir/libt1dep.so"
    221   main_obj="$dir/main.o"
    222   exe="$dir/main"
    223   run_cmd "$label:dep-cc" "$dir/dep-cc.log" \
    224     "$HOSTED" cc "$token" -O1 -fPIC -c "$KITCHEN/shared_dep.c" -o "$dep_obj" || return 0
    225   run_cmd "$label:dep-so" "$dir/dep-so.log" \
    226     "$HOSTED" cc "$token" -shared "$dep_obj" -o "$dep_so" || return 0
    227   run_cmd "$label:main-cc" "$dir/main-cc.log" \
    228     "$HOSTED" cc "$token" -O1 -c "$KITCHEN/shared_main.c" -o "$main_obj" || return 0
    229   run_cmd "$label:main-link" "$dir/main-link.log" \
    230     "$HOSTED" cc "$token" "$main_obj" -L "$dir" -lt1dep -o "$exe" || return 0
    231   if [ -s "$dep_so" ] && [ -s "$exe" ]; then kit_pass "$label"; else kit_fail "$label" "shared linked artifact missing"; fi
    232 }
    233 
    234 apple_sdk_path() {
    235   local sdk="$1"
    236   xcrun --sdk "$sdk" --show-sdk-path 2>/dev/null || true
    237 }
    238 
    239 apple_lane() {
    240   local lane="$1" triple="$2" sdk_name="$3" label="$1" sdk dir obj exe
    241   match_selector "$lane" || return 0
    242   if [ "$(uname -s 2>/dev/null)" != Darwin ]; then
    243     kit_skip "$label" "$sdk_name SDK requires Darwin host"
    244     return 0
    245   fi
    246   sdk="$(apple_sdk_path "$sdk_name")"
    247   if [ -z "$sdk" ] || [ ! -d "$sdk" ]; then
    248     kit_skip "$label" "$sdk_name SDK unavailable"
    249     return 0
    250   fi
    251   dir="$WORK/$label"
    252   mkdir -p "$dir"
    253   obj="$dir/exit.o"
    254   exe="$dir/exit"
    255   run_cmd "$label:cc" "$dir/cc.log" \
    256     "$KIT" cc -target "$triple" --sysroot "$sdk" -O1 -c "$CASES/exit.c" -o "$obj" || return 0
    257   run_cmd "$label:ld" "$dir/ld.log" \
    258     "$KIT" cc -target "$triple" --sysroot "$sdk" "$obj" -lc -o "$exe" || return 0
    259   if [ -s "$exe" ]; then kit_pass "$label"; else kit_fail "$label" "linked artifact missing"; fi
    260 }
    261 
    262 freestanding_triple() {
    263   case "$1" in
    264     aa64) echo aarch64-none-elf ;;
    265     x64) echo x86_64-none-elf ;;
    266     rv64) echo riscv64-none-elf ;;
    267     rv32) echo riscv32-none-elf ;;
    268     arm32) echo arm-none-eabi ;;
    269     *) return 1 ;;
    270   esac
    271 }
    272 
    273 freestanding_extra_flags() {
    274   case "$1" in
    275     rv32) printf '%s\n' "-march=rv32imafc_zicsr_zifencei -mabi=ilp32f" ;;
    276     arm32) printf '%s\n' "-mcpu=cortex-m3 -mfloat-abi=soft" ;;
    277     *) printf '\n' ;;
    278   esac
    279 }
    280 
    281 freestanding_lane() {
    282   local arch="$1" token="freestanding-$1" triple dir obj exe extra
    283   match_selector "$token" || return 0
    284   triple="$(freestanding_triple "$arch")" || {
    285     kit_skip "$token" "unsupported freestanding arch"
    286     return 0
    287   }
    288   dir="$WORK/$token"
    289   mkdir -p "$dir"
    290   obj="$dir/exit.o"
    291   exe="$dir/exit.elf"
    292   extra="$(freestanding_extra_flags "$arch")"
    293   # shellcheck disable=SC2086
    294   run_cmd "$token:cc" "$dir/cc.log" \
    295     "$KIT" cc -target "$triple" $extra -O1 -ffreestanding -nostdlib \
    296       -c "$CASES/exit.c" -o "$obj" || return 0
    297   run_cmd "$token:ld" "$dir/ld.log" \
    298     "$KIT" ld -e main -o "$exe" "$obj" || return 0
    299   if [ -s "$exe" ]; then kit_pass "$token"; else kit_fail "$token" "linked artifact missing"; fi
    300 }
    301 
    302 enqueue_lane() {
    303   local label="$1" id out
    304   shift
    305   id=$(t1_step_id "$label")
    306   out="$PARALLEL_DIR/$id.out"
    307   printf '%s\t%s\n' "$label" "$out" >> "$PARALLEL_DIR/order"
    308   t1_parallel_wait_for_slot "$T1_CROSS_JOBS"
    309   "$@" > "$out" 2>&1 &
    310 }
    311 
    312 replay_and_exit() {
    313   local combined="$PARALLEL_DIR/combined.out" pass fail skip failures skips
    314   : > "$combined"
    315   while IFS="$(printf '\t')" read -r label out; do
    316     [ -n "$label" ] || continue
    317     cat "$out"
    318     cat "$out" >> "$combined"
    319   done < "$PARALLEL_DIR/order"
    320 
    321   pass=$(awk '/^[[:space:]]+PASS[[:space:]]/{n++} END{print n+0}' "$combined")
    322   fail=$(awk '/^[[:space:]]+FAIL[[:space:]]/{n++} END{print n+0}' "$combined")
    323   skip=$(awk '/^[[:space:]]+SKIP[[:space:]]/{n++} END{print n+0}' "$combined")
    324   failures=$(awk '/^[[:space:]]+FAIL[[:space:]]/{printf " %s", $2}' "$combined")
    325   skips=$(awk '/^[[:space:]]+SKIP[[:space:]]/{printf " %s", $2}' "$combined")
    326 
    327   [ -n "$failures" ] && printf '\ntest-t1-cross: failures:%s\n' "$failures"
    328   [ -n "$skips" ] && printf 'test-t1-cross: skipped:%s\n' "$skips"
    329   printf '\ntest-t1-cross: %d pass, %d fail, %d skip\n' "$pass" "$fail" "$skip"
    330 
    331   [ "$fail" -gt 0 ] && exit 1
    332   if [ "${KIT_SKIP_IS_FAILURE:-0}" = "1" ] && [ "$skip" -gt 0 ] &&
    333      [ "${KIT_TEST_ALLOW_SKIP:-0}" != "1" ]; then
    334     exit 1
    335   fi
    336   exit 0
    337 }
    338 
    339 rm -f "$PARALLEL_DIR/order"
    340 : > "$PARALLEL_DIR/order"
    341 T1_CROSS_JOBS=$(t1_parallel_jobs) || exit $?
    342 
    343 for arch in aa64 x64 rv64; do
    344   enqueue_lane "linux-glibc-$arch" hosted_lane "linux-glibc-$arch" default
    345   enqueue_lane "linux-glibc-$arch:shared" linux_shared_lane "linux-glibc-$arch"
    346   enqueue_lane "linux-musl-$arch:static" hosted_lane "linux-musl-$arch" static
    347   enqueue_lane "linux-musl-$arch:dynamic" hosted_lane "linux-musl-$arch" dynamic
    348   enqueue_lane "linux-musl-$arch:shared" linux_shared_lane "linux-musl-$arch"
    349   enqueue_lane "freebsd-$arch" hosted_lane "freebsd-$arch" default
    350 done
    351 
    352 for arch in aa64 x64; do
    353   enqueue_lane "windows-$arch" hosted_lane "windows-$arch" default
    354   enqueue_lane "macos-$arch" hosted_lane "macos-$arch" default
    355 done
    356 
    357 enqueue_lane android-aa64 android_lane
    358 
    359 enqueue_lane ios-aa64 apple_lane ios-aa64 arm64-apple-ios iphoneos
    360 enqueue_lane ios-sim-aa64 apple_lane ios-sim-aa64 arm64-apple-ios-simulator iphonesimulator
    361 enqueue_lane ios-sim-x64 apple_lane ios-sim-x64 x86_64-apple-ios-simulator iphonesimulator
    362 
    363 for arch in aa64 x64 rv64 rv32 arm32; do
    364   enqueue_lane "freestanding-$arch" freestanding_lane "$arch"
    365 done
    366 
    367 wait || true
    368 replay_and_exit