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