test.mk (39374B)
1 # Data-driven tests. Included from the top-level Makefile. 2 # 3 # - test-driver: aggregate alias that runs all test-driver-* targets. 4 # - test-driver-cc: narrow CLI behavior checks that do not belong to a specific 5 # frontend/linker corpus. Depends on the kit driver binary. 6 # - test-pp: aggregate alias that runs test-pp-ok and test-pp-err. 7 # - test-pp-ok: C preprocessor success cases; depends on the kit driver binary. 8 # - test-elf: ELF roundtrip harness in test/elf/; depends only on 9 # libkit.a and compiles its own test binaries against it. Skipped 10 # layers are reported (set KIT_TEST_ALLOW_SKIP=1 to allow skips). 11 # - test-ar: in-process ar reader/writer tests; depends only on 12 # libkit.a. Set KIT_AR_TEST_HOST=1 to also dump produced bytes 13 # to /tmp and run the host's `ar t` / `nm --print-armap` as a 14 # cross-check. 15 # - test-driver-ar: scenario-driven CLI harness for `kit ar`. Each 16 # case under test/ar/cases/ runs a small script and diffs stdout. 17 # Depends on the kit driver binary. 18 # - test-link: linker + JIT behavioral harness in test/link/; three paths 19 # per case (roundtrip R, ELF exec E, JIT J). Depends only on libkit.a. 20 # Set KIT_TEST_ALLOW_SKIP=1 to allow skipped layers. 21 # - test-macho: Mach-O variant of test-link; defaults to roundtrip+JIT 22 # paths because hosted Mach-O executable execution is target/SDK-specific. 23 # - test-parse: aggregate alias that runs test-parse-ok and test-parse-err. 24 # - test-parse-ok: file-driven C parser success harness in test/parse/; each 25 # case is a .c source file. Built against the public kit.h surface; 26 # reuses kit-roundtrip, link-exe-runner, and jit-runner. 27 # - test-asm: aggregate alias over the per-arch asm lanes test-asm-aa64, 28 # test-asm-x64 and test-asm-rv64. The file-driven assembler/disassembler 29 # harness in test/asm/ runs one arch per invocation (KIT_TEST_ARCH) over 30 # three sub-corpora (encode/, decode/, listing/), one mode per sub-dir. 31 # aa64 runs the full path set (incl. native exec on aa64 hosts); x64/rv64 32 # run the host-independent encode/decode/listing lanes only. See doc/ASM.md. 33 34 TEST_TARGETS = \ 35 test-cf-corpus-selftest \ 36 test-aa64-inline \ 37 test-abi-classify \ 38 test-ar \ 39 test-asm \ 40 test-asm-aa64 \ 41 test-asm-x64 \ 42 test-asm-rv64 \ 43 test-disasm-complete \ 44 test-asm-roundtrip \ 45 test-asm-roundtrip-exec \ 46 test-asm-symmetry \ 47 test-asm-roundtrip-toy \ 48 test-hostas-toy \ 49 test-hostas-cross \ 50 test-diff-llvm \ 51 test-bootstrap-toy \ 52 test-bootstrap-toy-debug \ 53 test-bootstrap-toy-release \ 54 test-bounce \ 55 test-cbackend \ 56 test-cg-api \ 57 test-coff \ 58 test-coff-mingw-import \ 59 test-coff-windows-ucrt \ 60 test-debug \ 61 test-dbg \ 62 test-driver \ 63 test-driver-ar \ 64 test-driver-cas \ 65 test-driver-cc \ 66 test-driver-compile \ 67 test-driver-objcopy \ 68 test-driver-objdump \ 69 test-driver-pkg \ 70 test-driver-strings \ 71 test-driver-tools \ 72 test-hash \ 73 test-driver-strip \ 74 test-dwarf \ 75 test-elf \ 76 test-emu \ 77 test-emu-unit \ 78 test-interp \ 79 test-interp-emu \ 80 test-interp-toy \ 81 test-ir-recorder \ 82 test-isa \ 83 test-lib-deps \ 84 test-libc \ 85 test-libc-glibc \ 86 test-libc-glibc-rv64 \ 87 test-libc-musl \ 88 test-libc-musl-rv64 \ 89 test-link \ 90 test-link-reloc-uleb128 \ 91 test-macho \ 92 test-native-direct-target \ 93 test-opt \ 94 test-parse \ 95 test-parse-err \ 96 test-parse-ok \ 97 test-parse-rv64-wide \ 98 test-pp \ 99 test-pp-err \ 100 test-pp-ok \ 101 test-rt-headers \ 102 test-rt-runtime \ 103 test-link-x64 \ 104 test-rv64-inline \ 105 test-rv64-jit \ 106 test-rv64-tls-link \ 107 test-smoke-rv64 \ 108 test-smoke-x64 \ 109 test-toy \ 110 test-wasm \ 111 test-wasm-c \ 112 test-wasm-front \ 113 test-wasm-target \ 114 test-wasm-toy \ 115 test-x64-dbg \ 116 test-x64-inline 117 118 DEFAULT_TEST_TARGETS = \ 119 test-cf-corpus-selftest \ 120 test-driver \ 121 test-pp \ 122 test-elf \ 123 test-coff \ 124 test-ar \ 125 test-link \ 126 test-toy \ 127 test-dwarf \ 128 test-debug \ 129 test-parse \ 130 test-asm \ 131 test-asm-roundtrip \ 132 test-isa \ 133 test-aa64-inline \ 134 test-rv64-inline \ 135 test-rv64-jit \ 136 test-rv64-tls-link \ 137 test-emu \ 138 test-emu-unit \ 139 test-interp \ 140 test-interp-emu \ 141 test-x64-inline \ 142 test-x64-dbg \ 143 test-rt-headers \ 144 test-lib-deps \ 145 test-cg-api \ 146 test-abi-classify \ 147 test-ir-recorder \ 148 test-native-direct-target \ 149 test-opt \ 150 test-asm-symmetry \ 151 test-link-reloc-uleb128 \ 152 test-dbg \ 153 test-disasm-complete \ 154 test-macho \ 155 test-interp-toy \ 156 test-wasm \ 157 test-libc \ 158 test-link-x64 \ 159 test-rt-runtime \ 160 test-bounce \ 161 bootstrap \ 162 test-bootstrap-toy 163 164 .PHONY: test $(TEST_TARGETS) 165 166 test: $(DEFAULT_TEST_TARGETS) 167 168 # Unit-test binary build rules: two regimes (public vs internal interface). 169 include test/lib/unit.mk 170 171 # Provision the pinned per-arch container rootfs images that exec_target.sh runs 172 # kit-emitted binaries inside. This is the ONLY test step that touches the 173 # network: the cross-arch exec harnesses (toy/parse/link ... path X/E/L) run with 174 # `podman run --pull=never`, so without these images those paths SKIP. Run once, 175 # and again only after the pin in test/lib/test_images.sh changes. FORCE=1 176 # re-pulls. The images are pinned per-arch by content digest, so they coexist in 177 # local storage and can never clobber one another. 178 .PHONY: test-images 179 test-images: 180 @bash test/lib/pull_test_images.sh 181 182 # Hermetic self-test of the shared corpus harness engine (test/lib/kit_corpus.sh): 183 # asserts serial==parallel determinism, SKIP-NA, and the parallel-safety 184 # invariant (exec_target queued only on the parent, never in a worker). No 185 # kit binary / podman / qemu needed. 186 test-cf-corpus-selftest: 187 @bash test/lib/kit_corpus_selftest.sh 188 189 test-driver: test-driver-cc test-driver-compile test-driver-ar test-driver-cas test-driver-strip test-driver-objcopy test-driver-objdump test-driver-pkg test-driver-strings test-driver-tools 190 191 test-driver-cc: bin 192 @KIT=$(abspath $(BIN)) sh test/driver/run.sh 193 194 test-driver-compile: bin 195 @KIT=$(abspath $(BIN)) sh test/compile/run.sh 196 197 # test-cbackend: --emit=c C-source backend, driven through three 198 # frontends — parse-runner (C), toy-runner (toy), wasm-runner (wat/wasm). 199 # Each invokes its existing runner with paths=C so a single corpus per 200 # frontend exercises both the existing backends and the C backend. 201 # Together they prove the CGTarget seam is frontend-agnostic. 202 # Unimplemented CGTarget methods report as SKIP; see doc/CBACKEND.md. 203 KIT_CBACKEND_TEST_JOBS ?= $(if $(KIT_TEST_JOBS),$(KIT_TEST_JOBS),1) 204 test-cbackend: bin 205 @KIT_TEST_JOBS=$(KIT_CBACKEND_TEST_JOBS) KIT_TEST_PATHS=C KIT_TEST_ALLOW_SKIP=1 sh test/parse/run.sh 206 @KIT_TEST_JOBS=$(KIT_CBACKEND_TEST_JOBS) KIT_TEST_PATHS=C KIT=$(abspath $(BIN)) sh test/toy/run.sh 207 @KIT_TEST_JOBS=$(KIT_CBACKEND_TEST_JOBS) KIT_TEST_PATHS=C KIT=$(abspath $(BIN)) bash test/wasm/run.sh 208 209 # test-wasm-toy: opt-in Toy -> Wasm -> JIT roundtrip. Runs the toy corpus 210 # under the W path (compile -target wasm32-none, then `kit run` the .wasm, 211 # which routes back through the lang/wasm frontend to native CG). Most cases 212 # will fail or skip today; the target exists so progress on the Wasm CGTarget 213 # is visible without putting noise into the default `test` summary. 214 # Drop `KIT_TEST_ALLOW_SKIP=1` once the corpus is mostly green. 215 test-wasm-toy: bin 216 @KIT_TEST_PATHS=W KIT_TEST_ALLOW_SKIP=1 KIT=$(abspath $(BIN)) sh test/toy/run.sh 217 218 # test-wasm-c: opt-in C -> Wasm -> JIT roundtrip, the C-frontend analogue of 219 # test-wasm-toy. Runs the test/parse corpus under the W path (compile 220 # -target wasm32-none, then `kit run -e test_main` the .wasm, which routes 221 # back through the lang/wasm frontend to native CG). The C corpus exercises 222 # far more of the language than the toy corpus, so expect many SKIPs for 223 # not-yet-implemented Wasm lowerings; the target makes that progress visible 224 # without adding noise to the default `test` summary. Drop 225 # `KIT_TEST_ALLOW_SKIP=1` once the corpus is mostly green. 226 test-wasm-c: bin $(PARSE_RUNNER) 227 @KIT_TEST_PATHS=W KIT_TEST_ALLOW_SKIP=1 KIT=$(abspath $(BIN)) bash test/parse/run.sh 228 229 test-pp: test-pp-ok test-pp-err 230 231 test-pp-ok: bin 232 @KIT=$(abspath $(BIN)) test/pp/run.sh 233 234 test-pp-err: bin 235 @KIT=$(abspath $(BIN)) test/pp/run_errors.sh 236 237 # Best-effort kit binary build: Layer D needs build/kit, but the 238 # binary may not link until enough libkit symbols exist. The harness 239 # detects a missing binary and skips that layer; don't break test-elf 240 # when bin fails. 241 .PHONY: bin-soft 242 bin-soft: 243 -@$(MAKE) bin 2>/dev/null || true 244 245 AR_TEST_BIN = build/test/ar_test 246 247 test-ar: $(AR_TEST_BIN) 248 $(AR_TEST_BIN) 249 250 251 test-driver-ar: bin 252 @KIT=$(abspath $(BIN)) test/ar/run.sh 253 254 test-driver-cas: bin 255 @KIT=$(abspath $(BIN)) sh test/cas/run.sh 256 257 test-driver-strip: bin 258 @KIT=$(abspath $(BIN)) test/strip/run.sh 259 260 test-driver-objcopy: bin 261 @KIT=$(abspath $(BIN)) test/objcopy/run.sh 262 263 test-driver-objdump: bin 264 @KIT=$(abspath $(BIN)) sh test/objdump/run.sh 265 266 test-driver-pkg: bin 267 @KIT=$(abspath $(BIN)) sh test/pkg/run.sh 268 269 test-driver-strings: bin 270 @KIT=$(abspath $(BIN)) sh test/strings/run.sh 271 272 test-driver-tools: bin 273 @KIT=$(abspath $(BIN)) sh test/tools/run.sh 274 275 # DWARF consumer unit test: builds a hand-crafted DWARF-bearing ELF in 276 # memory and exercises every kit_dwarf_* entry. It reaches into the 277 # internal object builder to synthesize the fixture, so link individual 278 # lib objects rather than libkit.a (which hides internal symbols). 279 DWARF_TEST_BIN = build/test/dwarf_test 280 281 test-dwarf: $(DWARF_TEST_BIN) 282 $(DWARF_TEST_BIN) 283 284 285 # DWARF producer self-roundtrip unit test. Drives Debug directly, calls 286 # debug_emit, asserts the produced sections have valid DWARF 5 structure 287 # (length fields, version, address sizes, expected relocations against 288 # function symbol). Deliberately bypasses the consumer (kit_dwarf_open) 289 # so encoder bugs aren't masked by matching decoder bugs. 290 DEBUG_TEST_BIN = build/test/debug_roundtrip_unit 291 CFI_TEST_BIN = build/test/debug_cfi_unit 292 293 test-debug: $(DEBUG_TEST_BIN) $(CFI_TEST_BIN) 294 $(DEBUG_TEST_BIN) 295 $(CFI_TEST_BIN) 296 297 298 # CFI/.eh_frame producer roundtrip for aa64/rv64/x64 (validates the per-arch 299 # CIE template: code/data-align, return-address reg, CFA-init reg). 300 301 test-dbg: bin 302 @KIT=$(abspath $(BIN)) sh test/dbg/run.sh 303 304 .PHONY: test-dbg-red 305 test-dbg-red: bin 306 @KIT=$(abspath $(BIN)) DBG_STRICT_XFAIL=1 sh test/dbg/run.sh 307 308 # aa64 ISA descriptor-table unit test (doc/ASM.md phase 2). Covers 309 # every AA64Format the table maps and the alias-precedence invariant 310 # (first-match disasm picks the alias spelling over the canonical 311 # form). Internal arch/ surface — needs -Isrc. 312 AA64_ISA_TEST_BIN = build/test/aa64_isa_test 313 RV64_DECODE_TEST_BIN = build/test/rv64_decode_test 314 315 test-isa: $(AA64_ISA_TEST_BIN) $(RV64_DECODE_TEST_BIN) 316 $(AA64_ISA_TEST_BIN) 317 $(RV64_DECODE_TEST_BIN) 318 319 320 321 # aa64_sweep_gen: emits one representative encoding per disasm-table row for the 322 # asm<->disasm self-symmetry sweep (test/asm/symmetry.sh). Needs the internal 323 # arch/aa64/isa.h surface, so -Isrc + LIB_OBJS like the ISA unit test. 324 AA64_SWEEP_GEN = build/test/aa64_sweep_gen 325 326 # test-emu: emulator end-to-end integration test. Builds tiny in-memory rv64 327 # ELFs and runs them to their exit syscall, asserting the exit code — entirely 328 # through the PUBLIC kit_emu_* API, so it links the public archive ($(LIB_AR), 329 # whose `ld -r` step localizes internal symbols). -Isrc is only for the 330 # header-only rv64 encoders / ELF constants the in-memory ELF builders use. 331 EMU_RV64_TEST_BIN = build/test/emu_rv64_test 332 333 test-emu: $(EMU_RV64_TEST_BIN) 334 $(EMU_RV64_TEST_BIN) 335 336 $(EMU_RV64_TEST_BIN): test/emu/rv64_smoke_test.c $(UNIT_HDR_DEPS) $(LIB_AR) 337 @mkdir -p $(dir $@) 338 $(CC) $(HOST_CFLAGS) -Iinclude -Isrc -Itest test/emu/rv64_smoke_test.c $(LIB_AR) -o $@ 339 340 # RISC-V ULEB128 diff-reloc application unit test. link_reloc_apply is an 341 # internal (hidden) symbol, so link the raw lib objects like the other 342 # internal-surface unit tests rather than libkit.a. 343 RELOC_ULEB128_TEST_BIN = build/test/reloc_uleb128_unit 344 345 test-link-reloc-uleb128: $(RELOC_ULEB128_TEST_BIN) 346 $(RELOC_ULEB128_TEST_BIN) 347 348 # test-emu-unit: white-box unit tests for the emulator's INTERNAL units (rv64 349 # decoder, EmuAddrSpace, Linux syscall handler) that have no public API. Reaches 350 # internal symbols -> links $(LIB_OBJS) (mirrors test-interp), not the archive. 351 EMU_RV64_UNIT_TEST_BIN = build/test/emu_rv64_unit_test 352 353 test-emu-unit: $(EMU_RV64_UNIT_TEST_BIN) 354 $(EMU_RV64_UNIT_TEST_BIN) 355 356 357 # test-interp: threaded-bytecode interpreter unit smoke test. Builds tiny CG IR 358 # by hand, runs opt_run_o1_interp + interp_lower + the engine, asserts the 359 # returned value. Reaches internal opt/interp symbols -> links $(LIB_OBJS) and 360 # needs -Isrc (mirrors test-opt). 361 INTERP_SMOKE_TEST_BIN = build/test/interp_smoke_test 362 363 test-interp: $(INTERP_SMOKE_TEST_BIN) 364 $(INTERP_SMOKE_TEST_BIN) 365 366 367 # test-interp-emu: differential test of the emulator's INTERP execution mode 368 # (doc/INTERPRETER.md Phase 4). Builds a tiny rv64 ELF with SD/LD/ecall and runs 369 # it through kit_emu_run in JIT and INTERP modes (both -O1), asserting the exit 370 # codes match. Public-API only, but links $(LIB_OBJS) like test-interp to dodge 371 # the visibility-hidden archive's localized internals. 372 INTERP_EMU_TEST_BIN = build/test/rv64_interp_smoke_test 373 374 test-interp-emu: $(INTERP_EMU_TEST_BIN) 375 $(INTERP_EMU_TEST_BIN) 376 377 378 # test-interp-toy: run the toy suite's interpreter (--no-jit) path only, 379 # asserting it matches the golden exit codes (and SKIPping unimplemented ops). 380 test-interp-toy: bin 381 @KIT=$(abspath $(BIN)) KIT_TEST_PATHS=I bash test/toy/run.sh 382 383 CG_API_TEST_BIN = build/test/cg_api_test 384 CG_SWITCH_TEST_BIN = build/test/cg_switch_test 385 CG_FP_CMP_TEST_BIN = build/test/cg_fp_cmp_test 386 STRENGTH_REDUCE_TEST_BIN = build/test/strength_reduce_test 387 HASH_TEST_BIN = build/test/hash_test 388 ABI_CLASSIFY_TEST_BIN = build/test/abi_classify_test 389 IR_RECORDER_TEST_BIN = build/test/ir_recorder_test 390 NATIVE_DIRECT_TARGET_TEST_BIN = build/test/native_direct_target_test 391 392 test-cg-api: $(CG_API_TEST_BIN) $(CG_SWITCH_TEST_BIN) $(CG_FP_CMP_TEST_BIN) \ 393 $(STRENGTH_REDUCE_TEST_BIN) 394 $(CG_API_TEST_BIN) 395 $(CG_SWITCH_TEST_BIN) 396 $(CG_FP_CMP_TEST_BIN) 397 $(STRENGTH_REDUCE_TEST_BIN) 398 399 test-hash: $(HASH_TEST_BIN) 400 $(HASH_TEST_BIN) 401 402 test-abi-classify: $(ABI_CLASSIFY_TEST_BIN) 403 $(ABI_CLASSIFY_TEST_BIN) 404 405 406 407 408 test-ir-recorder: $(IR_RECORDER_TEST_BIN) 409 $(IR_RECORDER_TEST_BIN) 410 411 412 test-native-direct-target: $(NATIVE_DIRECT_TARGET_TEST_BIN) 413 $(NATIVE_DIRECT_TARGET_TEST_BIN) 414 415 416 test-toy: bin 417 @KIT=$(abspath $(BIN)) test/toy/run.sh 418 419 # test-bootstrap-toy: run the Toy corpus through the bootstrapped (self-built) 420 # stage3 kit instead of the host-built binary, so the self-hosted compiler is 421 # exercised on real codegen (not just self-reproduction like `make bootstrap`). 422 # Split per build mode: -debug runs the debug stage3, -release the release 423 # (-O1) stage3; the aggregate target runs both. 424 test-bootstrap-toy: test-bootstrap-toy-debug test-bootstrap-toy-release 425 426 test-bootstrap-toy-debug: bootstrap-debug 427 @KIT='$(abspath $(BUILD_DIR)/debug/bootstrap/stage3/kit)' test/toy/run.sh 428 429 test-bootstrap-toy-release: bootstrap-release 430 @KIT='$(abspath $(BUILD_DIR)/release/bootstrap/stage3/kit)' test/toy/run.sh 431 432 433 # Public-API inline-asm backend tests. These emit a tiny function through CG, 434 # reopen the object through the public object reader, and assert the expected 435 # instruction bytes are present in .text. 436 AA64_INLINE_TEST_BIN = build/test/aa64_inline_test 437 438 test-aa64-inline: $(AA64_INLINE_TEST_BIN) 439 $(AA64_INLINE_TEST_BIN) 440 441 442 RV64_INLINE_TEST_BIN = build/test/rv64_inline_test 443 444 test-rv64-inline: $(RV64_INLINE_TEST_BIN) 445 $(RV64_INLINE_TEST_BIN) 446 447 448 # rv64 JIT smoke test. Builds a tiny rv64 ELF .o in memory, runs it 449 # through kit_link_session in JIT-output mode, and skips native execution 450 # on non-riscv64 hosts after exercising the JIT mapping/reloc path. 451 RV64_JIT_TEST_BIN = build/test/rv64_jit_test 452 453 test-rv64-jit: $(RV64_JIT_TEST_BIN) 454 @$(RV64_JIT_TEST_BIN); rc=$$?; \ 455 if [ $$rc -eq 77 ]; then \ 456 echo " (rv64_jit_test SKIPPED on non-rv64 host)"; \ 457 exit 0; \ 458 else \ 459 exit $$rc; \ 460 fi 461 462 463 # Link-only regression for rv64 TLS Local-Exec lowering (runs on any host). 464 test-rv64-tls-link: bin 465 @KIT='$(abspath $(BIN))' bash test/smoke/rv64_tls_link.sh 466 467 X64_INLINE_TEST_BIN = build/test/x64_inline_test 468 469 test-x64-inline: $(X64_INLINE_TEST_BIN) 470 $(X64_INLINE_TEST_BIN) 471 472 473 X64_DBG_TEST_BIN = build/test/x64_dbg_test 474 475 test-x64-dbg: $(X64_DBG_TEST_BIN) 476 $(X64_DBG_TEST_BIN) 477 478 # Reaches the internal arch/arch.h surface (arch_lookup, ArchDbgOps) -> links 479 # $(LIB_OBJS), not the archive, whose relocatable merge localizes non-public 480 # symbols (mirrors the aa64/rv64 arch unit tests above). 481 482 RT_HEADER_TEST_TARGETS = \ 483 aarch64-linux-gnu \ 484 x86_64-linux-gnu \ 485 riscv64-linux-gnu \ 486 aarch64-apple-darwin \ 487 x86_64-apple-darwin 488 489 test-rt-headers: bin 490 @set -e; \ 491 for target in $(RT_HEADER_TEST_TARGETS); do \ 492 out="build/test/rt-headers/$$target/smoke.o"; \ 493 mkdir -p "$$(dirname "$$out")"; \ 494 $(BIN) cc -target "$$target" -Werror -c test/rt/smoke.c -o "$$out"; \ 495 done 496 497 # Arch token -> linux rt variant target. The cross-target test harnesses link 498 # the matching LINUX runtime archive (compiler-rt-style helpers like 499 # __kit_sext64ti, __kit_assert_fail) rather than the native `rt` target, 500 # which builds only the host's own variant. Shared by the single-arch 501 # parse/asm/macho/link tests (via KIT_TEST_ARCH/TEST_RT_DEP) and by 502 # test-rt-runtime, which sweeps several arches at once. 503 KIT_TEST_ARCH ?= aa64 504 _TEST_RT_aa64 = rt-aarch64-linux 505 _TEST_RT_aarch64 = rt-aarch64-linux 506 _TEST_RT_arm64 = rt-aarch64-linux 507 _TEST_RT_x64 = rt-x86_64-linux 508 _TEST_RT_x86_64 = rt-x86_64-linux 509 _TEST_RT_amd64 = rt-x86_64-linux 510 _TEST_RT_rv64 = rt-riscv64-linux 511 _TEST_RT_riscv64 = rt-riscv64-linux 512 TEST_RT_DEP = $(_TEST_RT_$(KIT_TEST_ARCH)) 513 514 # test-rt-runtime compiles each case for the configured arches and links it 515 # against that arch's LINUX runtime archive, so it must depend on each variant 516 # (not the host `rt`). A stale per-arch archive otherwise silently breaks the 517 # link — e.g. a dropped __kit_assert_fail weak def surfaces as an undefined 518 # reference. KIT_RT_RUNTIME_ARCHES mirrors the default in test/rt/run.sh. 519 KIT_RT_RUNTIME_ARCHES ?= aa64 x64 rv64 520 RT_RUNTIME_DEPS := $(foreach a,$(KIT_RT_RUNTIME_ARCHES),$(_TEST_RT_$(a))) 521 522 test-rt-runtime: bin $(RT_RUNTIME_DEPS) $(LINK_EXE_RUNNER) 523 @bash test/rt/run.sh 524 525 # Test harness binaries shared by test-elf and test-link. 526 # Declared as Make targets (not built by the run.sh scripts) so they pick 527 # up libkit.a changes deterministically. 528 # 529 # HARNESS_CFLAGS drops -Wpedantic from the normal host flags; the runners cast 530 # kit_jit_lookup's void* to a function pointer, which pedantic rejects under 531 # C11. 532 HARNESS_CFLAGS = $(filter-out -Wpedantic,$(HOST_CFLAGS)) -Iinclude -Itest 533 534 ROUNDTRIP_BIN = build/test/kit-roundtrip 535 ROUNDTRIP_BIN_MACHO = build/test/kit-roundtrip-macho 536 ROUNDTRIP_BIN_COFF = build/test/kit-roundtrip-coff 537 COFF_IMPORT_SMOKE_BIN = build/test/pe-import-smoke 538 COFF_IMPORT_MINGW_BIN = build/test/pe-import-mingw 539 COFF_DSO_FORWARDER_BIN = build/test/pe-dso-forwarder 540 COFF_MIXED_ARCHIVE_BIN = build/test/pe-mixed-archive 541 LINK_EXE_RUNNER = build/test/link-exe-runner 542 JIT_RUNNER = build/test/jit-runner 543 PARSE_RUNNER = build/test/parse-runner 544 ASM_RUNNER = build/test/asm-runner 545 WASM_TOOL = build/test/wasm-tool 546 547 $(ROUNDTRIP_BIN): test/elf/kit-roundtrip.c $(LIB_AR) 548 @mkdir -p $(dir $@) 549 $(CC) $(HARNESS_CFLAGS) test/elf/kit-roundtrip.c $(LIB_AR) -o $@ 550 551 # Mach-O peer of kit-roundtrip — read_macho + emit_macho. Used by 552 # test-link's path R when KIT_TEST_OBJ=macho. 553 $(ROUNDTRIP_BIN_MACHO): test/macho/kit-roundtrip-macho.c $(LIB_AR) 554 @mkdir -p $(dir $@) 555 $(CC) $(HARNESS_CFLAGS) -Isrc test/macho/kit-roundtrip-macho.c $(LIB_AR) -o $@ 556 557 # PE/COFF round-trip harness (test/coff/). All-in-one binary: builds 558 # hand-crafted ObjBuilders and asserts emit_coff/read_coff round-trip 559 # stability for both x86_64-windows and aarch64-windows. 560 $(ROUNDTRIP_BIN_COFF): test/coff/kit-roundtrip-coff.c $(LIB_OBJS) 561 @mkdir -p $(dir $@) 562 $(CC) $(HARNESS_CFLAGS) -Isrc test/coff/kit-roundtrip-coff.c $(LIB_OBJS) -o $@ 563 564 # PE import-directory smoke test (test/coff/pe-import-smoke.c). 565 # Exercises the full chain: short-import shim bytes -> link_add_obj_bytes 566 # (reclassified as DSO) -> link_resolve -> link_emit_coff. Verifies the 567 # produced PE32+ via x86_64-w64-mingw32-objdump; skips cleanly if absent. 568 $(COFF_IMPORT_SMOKE_BIN): test/coff/pe-import-smoke.c $(LIB_OBJS) 569 @mkdir -p $(dir $@) 570 $(CC) $(HARNESS_CFLAGS) -Isrc test/coff/pe-import-smoke.c $(LIB_OBJS) -o $@ 571 572 # PE import test against a real mingw archive (test/coff/pe-import-mingw.c). 573 # Exercises the long-form import-archive absorption path 574 # (link_add_archive_bytes -> classify_coff_archive_member). Skips cleanly 575 # when the mingw toolchain isn't installed. 576 $(COFF_IMPORT_MINGW_BIN): test/coff/pe-import-mingw.c $(LIB_OBJS) 577 @mkdir -p $(dir $@) 578 $(CC) $(HARNESS_CFLAGS) -Isrc test/coff/pe-import-mingw.c $(LIB_OBJS) -o $@ 579 580 # read_coff_dso forwarder-export contract (test/coff/pe-dso-forwarder.c). 581 # Synthesizes a tiny PE32+ DLL with one direct and one forwarder export 582 # and asserts both surface as OBJ_SEC_NONE globals on the ObjBuilder. 583 $(COFF_DSO_FORWARDER_BIN): test/coff/pe-dso-forwarder.c $(LIB_OBJS) 584 @mkdir -p $(dir $@) 585 $(CC) $(HARNESS_CFLAGS) -Isrc test/coff/pe-dso-forwarder.c $(LIB_OBJS) -o $@ 586 587 # Mixed-member archive (test/coff/pe-mixed-archive.c). Verifies that 588 # one archive containing both a short-import member and a long-form 589 # COFF object with a defined data symbol satisfies references through 590 # both shapes — the same composition libucrt.a uses (API-set imports 591 # alongside lib64_libucrt_extra_a-*.o helpers). 592 $(COFF_MIXED_ARCHIVE_BIN): test/coff/pe-mixed-archive.c $(LIB_OBJS) 593 @mkdir -p $(dir $@) 594 $(CC) $(HARNESS_CFLAGS) -Isrc test/coff/pe-mixed-archive.c $(LIB_OBJS) -o $@ 595 596 $(LINK_EXE_RUNNER): test/link/harness/link_exe_runner.c $(LIB_AR) 597 @mkdir -p $(dir $@) 598 $(CC) $(HARNESS_CFLAGS) test/link/harness/link_exe_runner.c $(LIB_AR) -o $@ 599 600 $(JIT_RUNNER): test/link/harness/jit_runner.c $(LIB_AR) 601 @mkdir -p $(dir $@) 602 $(CC) $(HARNESS_CFLAGS) test/link/harness/jit_runner.c $(LIB_AR) -o $@ 603 604 $(PARSE_RUNNER): test/parse/harness/parse_runner.c $(LIB_AR) 605 @mkdir -p $(dir $@) 606 $(CC) $(HARNESS_CFLAGS) test/parse/harness/parse_runner.c $(LIB_AR) -o $@ 607 608 $(ASM_RUNNER): test/asm/harness/asm_runner.c $(LIB_AR) 609 @mkdir -p $(dir $@) 610 $(CC) $(HARNESS_CFLAGS) test/asm/harness/asm_runner.c $(LIB_AR) -o $@ 611 612 $(WASM_TOOL): test/wasm/harness/wasm_tool.c $(LIB_AR) 613 @mkdir -p $(dir $@) 614 $(CC) $(HARNESS_CFLAGS) -I. test/wasm/harness/wasm_tool.c $(LIB_AR) -o $@ 615 616 test-elf: lib bin-soft $(ROUNDTRIP_BIN) 617 KIT_ELF_UNIT_CFLAGS='$(HOST_MODE_CFLAGS)' \ 618 KIT_ELF_UNIT_LDFLAGS='$(HOST_MODE_LDFLAGS)' \ 619 bash test/elf/run.sh 620 621 # PE/COFF round-trip harness plus optional hosted Windows smoke. The 622 # UCRT smoke self-skips when llvm-mingw is not installed. 623 test-coff: lib bin rt-aarch64-windows $(ROUNDTRIP_BIN_COFF) $(COFF_IMPORT_SMOKE_BIN) $(COFF_DSO_FORWARDER_BIN) $(COFF_MIXED_ARCHIVE_BIN) 624 $(ROUNDTRIP_BIN_COFF) 625 $(COFF_IMPORT_SMOKE_BIN) 626 $(COFF_DSO_FORWARDER_BIN) 627 $(COFF_MIXED_ARCHIVE_BIN) 628 bash test/coff/windows-ucrt-hosted-smoke.sh 629 bash test/coff/windows-system-dlls-smoke.sh 630 631 # Separate target so it can be skipped gracefully if mingw isn't 632 # installed. The test itself self-skips on missing tooling, but the 633 # build target only fires when explicitly requested. 634 test-coff-mingw-import: lib $(COFF_IMPORT_MINGW_BIN) 635 $(COFF_IMPORT_MINGW_BIN) 636 637 test-coff-windows-ucrt: bin rt-aarch64-windows 638 bash test/coff/windows-ucrt-hosted-smoke.sh 639 640 # The parse/asm/macho harnesses select a cross-target via KIT_TEST_ARCH 641 # (default aa64); the link rt dependency is resolved through the shared 642 # _TEST_RT_<arch> map defined above (near test-rt-runtime). 643 test-link: lib $(ROUNDTRIP_BIN) $(ROUNDTRIP_BIN_MACHO) $(LINK_EXE_RUNNER) $(JIT_RUNNER) 644 bash test/link/run.sh 645 646 # x64 ELF link/reloc-application coverage. test-link defaults to aa64, so 647 # kit's x64 static-link reloc fixups (R_X64_PLT32/GOTPCREL/TPOFF/...) were 648 # only ever run via a manual KIT_TEST_ARCH=x64 override. Opt-in (not in the 649 # default set) because the E path links + runs under podman/qemu-x86_64; the R 650 # path (roundtrip + reloc layout) runs on any host. 651 test-link-x64: lib rt-x86_64-linux $(ROUNDTRIP_BIN) $(LINK_EXE_RUNNER) $(JIT_RUNNER) 652 @KIT_TEST_ARCH=x64 KIT_TEST_PATHS=RE bash test/link/run.sh 653 654 test-macho: lib $(TEST_RT_DEP) $(ROUNDTRIP_BIN_MACHO) $(LINK_EXE_RUNNER) $(JIT_RUNNER) 655 KIT_TEST_OBJ=macho \ 656 KIT_TEST_ARCH=$${KIT_TEST_ARCH:-aa64} \ 657 KIT_TEST_PATHS=$${KIT_TEST_PATHS:-RJ} \ 658 KIT_TEST_ALLOW_SKIP=$${KIT_TEST_ALLOW_SKIP:-1} \ 659 bash test/link/run.sh 660 661 OPT_TEST_BIN = build/test/cg_ir_lower_test 662 TINY_INLINE_TEST_BIN = build/test/tiny_inline_test 663 664 test-opt: bin $(OPT_TEST_BIN) test-opt-tiny-inline test-opt-inline test-opt-zero-arg test-opt-static-prune-aa64 test-opt-aa64-tail test-opt-prologue-tier 665 $(OPT_TEST_BIN) 666 667 668 test-opt-tiny-inline: bin $(TINY_INLINE_TEST_BIN) 669 $(TINY_INLINE_TEST_BIN) 670 671 672 # Behavioral disasm check: tiny callee `bl` disappears from its caller at -O1. 673 test-opt-inline: bin 674 @KIT=$(abspath $(BIN)) bash test/opt/run.sh 675 676 # Behavioral disasm check: a pointer-typed null call arg is not routed through 677 # a scratch temp at -O1 (PERCALL.md item 3, "zero through a temp"). 678 test-opt-zero-arg: bin 679 @KIT=$(abspath $(BIN)) bash test/opt/zero_arg.sh 680 681 .PHONY: test-opt-static-prune-aa64 682 test-opt-static-prune-aa64: bin 683 @KIT=$(abspath $(BIN)) bash test/opt/static_prune_aa64.sh 684 685 .PHONY: test-opt-aa64-tail 686 test-opt-aa64-tail: bin 687 @KIT=$(abspath $(BIN)) bash test/opt/aa64_tail_call.sh 688 689 # Structural disasm check: the -O1 known-frame prologue cost-model tiers 690 # (aa64 reference + ported x64 slim/red-zone and rv64 leaf shapes). 691 .PHONY: test-opt-prologue-tier 692 test-opt-prologue-tier: bin 693 @KIT=$(abspath $(BIN)) bash test/opt/prologue_tier.sh 694 695 test-parse: test-parse-ok test-parse-err 696 697 test-parse-ok: lib $(TEST_RT_DEP) $(PARSE_RUNNER) $(ROUNDTRIP_BIN) $(LINK_EXE_RUNNER) $(JIT_RUNNER) 698 bash test/parse/run.sh 699 700 test-parse-err: lib $(PARSE_RUNNER) 701 sh test/parse/run_errors.sh 702 703 # test-asm: aggregate alias running every per-arch asm lane (aa64 + x64 + rv64) 704 # so `make test` covers all three through one target. The harness runs one arch 705 # per invocation (KIT_TEST_ARCH); each lane scopes its scratch per arch, so 706 # the prerequisites are safe to run in parallel under `make -j`. 707 test-asm: test-asm-aa64 test-asm-x64 test-asm-rv64 708 709 # test-asm-aa64: the reference lane. aa64 is the default cross-target, and on 710 # aa64 hosts the exec paths (D/E/J) run natively, so it uses the full default 711 # path set (HTLDJE). The Makefile owns the harness binaries so they inherit host 712 # flags consistently with the rest of the test suite. 713 test-asm-aa64: lib $(TEST_RT_DEP) $(ASM_RUNNER) $(LINK_EXE_RUNNER) $(JIT_RUNNER) 714 @KIT_TEST_ARCH=aa64 bash test/asm/run.sh 715 716 # x64/rv64 exercise the encode (H), decode (T) and listing (L) corpora on any 717 # host: H/T/L need no native execution (they only produce/compare bytes), so the 718 # exec paths (D/E/J) are deliberately excluded and left to the smoke/qemu 719 # targets. 720 test-asm-x64: lib $(ASM_RUNNER) 721 @KIT_TEST_ARCH=x64 KIT_TEST_PATHS=HTL bash test/asm/run.sh 722 test-asm-rv64: lib $(ASM_RUNNER) 723 @KIT_TEST_ARCH=rv64 KIT_TEST_PATHS=HT bash test/asm/run.sh 724 725 # Codegen round-trip completeness (doc/ASM_ROUNDTRIP_TESTING.md). These drive 726 # the `kit` binary itself (cc -S / as / objdump) over a C corpus rather than 727 # a hand-written asm corpus, so coverage tracks codegen automatically. 728 # 729 # test-disasm-complete L0: cc -S must decode every in-function word 730 # (no `.inst` markers). Host-independent, no exec. 731 # test-asm-roundtrip L0+L1: also assert cc -c bytes/relocs == cc -S | as. 732 # test-asm-roundtrip-exec L0+L1+L2: also run direct vs round-tripped object 733 # and compare exit codes (native arch; opt-in). 734 # 735 # Vertical slice: aa64 only for now; L1/L2 run at -O1 (branch-free), L0 at both 736 # opt levels. Broadening to -O0, other arches, and the default suite is tracked 737 # in doc/ASM_ROUNDTRIP_TESTING.md once -S symbolization (Phase 2) lands. 738 test-disasm-complete: bin 739 @KIT_TEST_ARCH=aa64 KIT_TEST_OPTS="O0 O1" KIT_TEST_PATHS=0 \ 740 bash test/asm/roundtrip.sh 741 test-asm-roundtrip: bin 742 @KIT_TEST_ARCH=aa64 KIT_TEST_OPTS="O0 O1" KIT_TEST_PATHS=01 \ 743 bash test/asm/roundtrip.sh 744 test-asm-roundtrip-exec: bin $(JIT_RUNNER) 745 @KIT_TEST_ARCH=aa64 KIT_TEST_OPTS="O0 O1" KIT_TEST_PATHS=012 \ 746 bash test/asm/roundtrip.sh 747 748 # test-asm-symmetry: asm<->disasm self-symmetry sweep (aa64). Decode-side sweeps 749 # every disasm-table form (decode->encode->decode fixed point); encode-side 750 # asserts every byte the assembler emits over the encode corpus is decodable. 751 # Catches encode/decode asymmetries the codegen round-trip can't reach (e.g. a 752 # form one tool handles and the other doesn't). Host-independent, no exec. 753 test-asm-symmetry: $(ASM_RUNNER) $(AA64_SWEEP_GEN) 754 @bash test/asm/symmetry.sh 755 756 # test-diff-llvm: differential cross-check of kit against llvm (aa64), as a 757 # second oracle. Encode lane: kit as vs llvm-mc bytes over the encode corpus. 758 # Disasm lane: cc -c bytes vs llvm-mc of cc -S (validates kit's disassembler; 759 # the benign same-section-call reloc-vs-resolve difference is recognized). 760 # Opt-in; skips cleanly when llvm-mc is absent. 761 test-diff-llvm: bin 762 @KIT_TEST_OPTS="O0 O1" bash test/asm/diff_llvm.sh 763 764 # test-asm-roundtrip-toy: L2 exec round-trip over the Toy corpus (native arch). 765 # Reuses the ~150 toy cases (full CG op set, exit-code oracle) for free 766 # round-trip coverage: kit cc -S | kit as | kit run, exit must match. 767 # Opt-in; native target. Found a real miscompile (dropped .inst) the hand 768 # corpus never reached. 769 test-asm-roundtrip-toy: bin 770 @bash test/asm/roundtrip_toy.sh 771 772 # test-hostas-toy: feed one native `cc -S` to BOTH kit's own `as` and clang (a 773 # third-party host assembler), link + run each, and assert the toy exit-code 774 # oracle. Only the assembler differs between the two lanes, so the clang lane is 775 # the real test: a standard assembler can't paper over a private-dialect quirk 776 # the way kit's own `as` can (cf. test/asm/diff_llvm.sh, but by execution). 777 # cc -S is now object-format-aware, so the native Mach-O clang lane GATES by 778 # default (both lanes 312/0); KIT_HOSTAS_ENFORCE_CLANG=0 demotes it to XFAIL. 779 # Opt-in; skips cleanly if clang is absent. 780 test-hostas-toy: bin 781 @bash test/asm/hostas_toy.sh 782 783 # test-hostas-cross: the same two-assembler-by-execution idea as test-hostas-toy, 784 # but CROSS — `cc -S -target <triple>` for ELF Linux arches (aarch64/x86_64/ 785 # riscv64), assembled by kit-as AND clang, linked static (+ the start.c crt) 786 # with kit ld, and run under podman/qemu via test/lib/exec_target.sh. Each 787 # target self-skips unless the host has a clang cross target, a runner, a 788 # working `cc -S | kit as` for that arch, and a passing bounded exec smoke — 789 # so it runs green on whatever the host supports (aarch64-linux today; x86_64 790 # pends the x64 cc -S symbolizer, riscv64 pends a working rv64 user-mode 791 # emulator). Opt-in; skips cleanly if clang/podman are absent. 792 test-hostas-cross: bin 793 @bash test/asm/hostas_cross.sh 794 795 test-wasm: test-wasm-front test-wasm-target test-wasm-toy 796 797 test-wasm-front: bin $(WASM_TOOL) $(LINK_EXE_RUNNER) $(JIT_RUNNER) 798 bash test/wasm/run.sh 799 800 # test-wasm-target: structural checks on `kit cc -target wasm32-none` 801 # output. test/wasm-target/run.sh is a Type C corpus harness whose lanes each 802 # compile a tiny C or toy fixture and assert a property of the produced module 803 # bytes (inline-asm opcodes, memory.copy/fill opcodes, exported "memory", 804 # (import ...) decls). Opt-in: not in the default `test` target because the 805 # checks depend on the bulk-memory + (import ...) backend work landing first. 806 test-wasm-target: bin 807 @KIT=$(abspath $(BIN)) bash test/wasm-target/run.sh 808 809 # test-smoke-x64: phase-1 sanity check for the multi-arch bring-up. Builds a 810 # tiny freestanding x86_64 ELF with clang --target=x86_64-linux-gnu and 811 # runs it through test/lib/exec_target.sh's podman/qemu pipeline, 812 # proving the harness end-to-end before any kit-emitted x64 bytes 813 # exist. Excluded from the default `test` target because it needs 814 # podman + lld; opt-in via `make test-smoke-x64`. 815 test-smoke-x64: 816 bash test/smoke/x64.sh 817 818 # test-smoke-rv64: phase-2 counterpart of test-smoke-x64. Builds a 819 # tiny freestanding riscv64 ELF with clang --target=riscv64-linux-gnu 820 # and runs it through test/lib/exec_target.sh, proving the rv64 lane 821 # of the harness end-to-end before any kit-emitted rv64 bytes 822 # exist. Excluded from the default `test` target because it needs 823 # qemu-riscv64 (or podman with riscv64 emulation) + lld; opt-in via 824 # `make test-smoke-rv64`. 825 test-smoke-rv64: 826 bash test/smoke/rv64.sh 827 828 # test-parse-rv64-wide: end-to-end coverage of the rv64 128-bit scalar types 829 # — __int128 (i128_*) and IEEE-754 binary128 long double (ldbl128_*) — built 830 # with kit and run on riscv64. Exercises the soft-float / i128 lowering to 831 # the compiler-rt-style runtime (fp_tf, fp_ti, int64), the LP64D register-pair 832 # ABI for 16-byte scalars, and the conditional-branch range fix that large 833 # soft-float helpers depend on. Opt-in (needs qemu-riscv64 or podman with 834 # riscv64 emulation), so excluded from the default `test` target; mirrors 835 # test-smoke-rv64. Run a single case with 836 # KIT_TEST_ARCH=rv64 bash test/parse/run.sh ldbl128_03_arith 837 test-parse-rv64-wide: lib rt-riscv64-linux $(PARSE_RUNNER) $(ROUNDTRIP_BIN) \ 838 $(LINK_EXE_RUNNER) 839 @KIT_TEST_ARCH=rv64 KIT_TEST_PATHS=RE bash test/parse/run.sh 128 840 841 # test-bounce: format-bounce stress test. Compiles small programs with 842 # kit, then bounces each object through chains of format conversions 843 # (ELF<->Mach-O<->COFF), partial links (ld -r), strip, and archive 844 # round-trips, relinks, and runs the result, asserting the exit code 845 # matches a host-cc reference. Stresses obj read/write/reloc, ar, and 846 # partial-link paths rather than the arches. Defaults to the host-native 847 # Linux arch (no emulation); sweep others with 848 # KIT_BOUNCE_ARCHES="aarch64 x64 rv64". Excluded from the default `test` 849 # target because it needs podman/qemu + a host cc; opt-in via 850 # `make test-bounce`. 851 test-bounce: $(BIN) 852 bash test/bounce/bounce.sh 853 854 # test-libc: aggregate alias that runs test-libc-musl and test-libc-glibc. 855 # test-libc-musl / test-libc-glibc: end-to-end static + dynamic libc link/run 856 # on aarch64. Each variant pulls its own pinned sysroot (podman, ~30s on 857 # first run) and shares the same case files under test/libc/cases/: 858 # 859 # test-libc-musl — Alpine 3.20 + musl 1.2.5 (test/libc/musl/) 860 # test-libc-glibc — Debian bookworm + glibc 2.36 (test/libc/glibc/) 861 # 862 # Both build build/rt/aarch64-linux/libkit_rt.a for soft-float / TF 863 # builtins, and run `kit ld` against the real libc.a (static) and 864 # libc.so / libc.so.6 (dynamic). Excluded from the 865 # default `test` target because they need podman; opt-in via 866 # `make test-libc-musl` / `make test-libc-glibc` (or `make test-libc` for both). 867 # 868 # Each sysroot is treated as a real prerequisite via its PROVENANCE 869 # marker so subsequent runs skip extraction and re-extract only when 870 # the file is removed (or extract.sh -f forces a rebuild). 871 MUSL_SYSROOT_MARKER = build/musl-sysroot/PROVENANCE 872 MUSL_SYSROOT_X64_MARKER = build/musl-sysroot-x64/PROVENANCE 873 MUSL_SYSROOT_RV64_MARKER = build/musl-sysroot-rv64/PROVENANCE 874 GLIBC_SYSROOT_MARKER = build/glibc-sysroot/PROVENANCE 875 GLIBC_SYSROOT_X64_MARKER = build/glibc-sysroot-x64/PROVENANCE 876 GLIBC_SYSROOT_RV64_MARKER = build/glibc-sysroot-rv64/PROVENANCE 877 878 $(MUSL_SYSROOT_MARKER): test/libc/musl/extract.sh test/libc/musl/Containerfile 879 @bash test/libc/musl/extract.sh 880 881 $(MUSL_SYSROOT_X64_MARKER): test/libc/musl/extract.sh test/libc/musl/Containerfile.x64 882 @bash test/libc/musl/extract.sh -a x64 883 884 $(MUSL_SYSROOT_RV64_MARKER): test/libc/musl/extract.sh test/libc/musl/Containerfile.rv64 885 @bash test/libc/musl/extract.sh -a rv64 886 887 $(GLIBC_SYSROOT_MARKER): test/libc/glibc/extract.sh test/libc/glibc/Containerfile 888 @bash test/libc/glibc/extract.sh 889 890 $(GLIBC_SYSROOT_X64_MARKER): test/libc/glibc/extract.sh test/libc/glibc/Containerfile.x64 891 @bash test/libc/glibc/extract.sh -a x64 892 893 $(GLIBC_SYSROOT_RV64_MARKER): test/libc/glibc/extract.sh test/libc/glibc/Containerfile.rv64 894 @bash test/libc/glibc/extract.sh -a rv64 895 896 # test-libc-musl / test-libc-glibc honor KIT_LIBC_ARCHES (default "aa64"; 897 # values: aa64, x64, rv64). Each enabled arch contributes its sysroot 898 # PROVENANCE marker and its rt archive to the prerequisite list, so 899 # `KIT_LIBC_ARCHES="aa64 x64" make test-libc-musl` builds both sysroots 900 # + both rt archives before the runner script picks them up. 901 KIT_LIBC_ARCHES ?= aa64 902 903 # Map an arch token to its musl/glibc sysroot marker and rt target. 904 _LIBC_MUSL_SYSROOT_aa64 = $(MUSL_SYSROOT_MARKER) 905 _LIBC_MUSL_SYSROOT_x64 = $(MUSL_SYSROOT_X64_MARKER) 906 _LIBC_MUSL_SYSROOT_rv64 = $(MUSL_SYSROOT_RV64_MARKER) 907 _LIBC_GLIBC_SYSROOT_aa64 = $(GLIBC_SYSROOT_MARKER) 908 _LIBC_GLIBC_SYSROOT_x64 = $(GLIBC_SYSROOT_X64_MARKER) 909 _LIBC_GLIBC_SYSROOT_rv64 = $(GLIBC_SYSROOT_RV64_MARKER) 910 _LIBC_RT_aa64 = rt-aarch64-linux 911 _LIBC_RT_x64 = rt-x86_64-linux 912 _LIBC_RT_rv64 = rt-riscv64-linux 913 914 LIBC_MUSL_DEPS = $(foreach a,$(KIT_LIBC_ARCHES),$(_LIBC_MUSL_SYSROOT_$(a)) $(_LIBC_RT_$(a))) 915 LIBC_GLIBC_DEPS = $(foreach a,$(KIT_LIBC_ARCHES),$(_LIBC_GLIBC_SYSROOT_$(a)) $(_LIBC_RT_$(a))) 916 917 test-libc: test-libc-musl test-libc-glibc 918 919 test-libc-musl: bin $(LIBC_MUSL_DEPS) 920 @KIT_LIBC_ARCHES="$(KIT_LIBC_ARCHES)" bash test/libc/musl/run.sh 921 922 test-libc-glibc: bin $(LIBC_GLIBC_DEPS) 923 @KIT_LIBC_ARCHES="$(KIT_LIBC_ARCHES)" bash test/libc/glibc/run.sh 924 925 test-libc-musl-rv64: 926 @$(MAKE) test-libc-musl KIT_LIBC_ARCHES=rv64 927 928 test-libc-glibc-rv64: 929 @$(MAKE) test-libc-glibc KIT_LIBC_ARCHES=rv64 930 931 # Fail if libkit.a depends on any external symbol not in the allowlist, or 932 # if a relocatable link exposes non-public global definitions. 933 # External dependency drift in either direction (new dep, or stale entry) is a 934 # failure. 935 # 936 # Inspect the RELEASE artifacts only: the debug build is ASan/UBSan-instrumented 937 # and pulls in __asan_*/__ubsan_* externals that are not part of the shipped 938 # library's dependency surface. 939 LIB_DEPS_RELEASE_DIR = build/release 940 LIB_DEPS_AR = $(LIB_DEPS_RELEASE_DIR)/libkit.a 941 LIB_DEPS_ACTUAL = $(LIB_DEPS_RELEASE_DIR)/libkit.deps.txt 942 LIB_RELOC = $(LIB_DEPS_RELEASE_DIR)/libkit.reloc.o 943 LIB_RELOC_BAD = $(LIB_DEPS_RELEASE_DIR)/libkit.reloc.bad-symbols.txt 944 945 test-lib-deps: 946 @$(MAKE) lib RELEASE=1 947 @mkdir -p $(dir $(LIB_DEPS_ACTUAL)) 948 @python3 scripts/lib_external_deps.py $(LIB_DEPS_AR) > $(LIB_DEPS_ACTUAL) 949 @diff -u scripts/lib_deps.allowlist $(LIB_DEPS_ACTUAL) \ 950 || { echo "libkit.a external symbol set drifted from scripts/lib_deps.allowlist"; exit 1; } 951 @python3 scripts/lib_reloc_defined_prefixes.py $(LIB_DEPS_AR) \ 952 --output $(LIB_RELOC) --ar $(AR) --cc $(CC) > $(LIB_RELOC_BAD) 953 @test ! -s $(LIB_RELOC_BAD) \ 954 || { echo "libkit relocatable link exposes non-public symbols"; cat $(LIB_RELOC_BAD); exit 1; }