kit

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

commit 3fbd50380ffc8175756f8decd961fa5f90e40c7c
parent e588f2ff4cc4f95d7eab3cfd1847b490eb157c5f
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Wed, 17 Jun 2026 16:26:13 -0700

test: expand tier1 kitchen coverage

Diffstat:
Mmk/flags.mk | 7++++---
Mmk/test.mk | 1+
Mtest/tier1/cross/run.sh | 48++++++++++++++++++++++++++++++++++++++++++++++++
Mtest/tier1/frontend/run-kitchen.sh | 58+++++++++++++++++++++++++++++++++++++++++++++-------------
Atest/tier1/kitchen/cross/shared_dep.c | 3+++
Atest/tier1/kitchen/cross/shared_main.c | 5+++++
Atest/tier1/kitchen/objlink/interop/clang_value.c | 3+++
Atest/tier1/kitchen/objlink/interop/kit_main.c | 5+++++
Mtest/tier1/manifests/system/debug-dwarf.txt | 2+-
Mtest/tier1/manifests/system/tools.txt | 4++++
Mtest/tier1/objlink/README.md | 2++
Atest/tier1/objlink/interop.sh | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtest/tier1/objlink/run.sh | 1+
Mtest/tier1/system/README.md | 12+++++++-----
Mtest/tier1/system/debug-dwarf.sh | 3++-
15 files changed, 222 insertions(+), 23 deletions(-)

diff --git a/mk/flags.mk b/mk/flags.mk @@ -118,12 +118,13 @@ KIT_VERSION_DEFS = -DKIT_VERSION_STR='"$(KIT_VERSION)"' \ VERSION_CONFIG = $(BUILD_DIR)/.version-config $(VERSION_CONFIG): FORCE @mkdir -p $(dir $@) - @{ \ + @tmp="$@.$$$$.tmp"; \ + { \ printf '%s\n' 'KIT_VERSION=$(KIT_VERSION)'; \ printf '%s\n' 'KIT_BUILD_ID=$(KIT_BUILD_ID)'; \ printf '%s\n' 'KIT_HOST_TRIPLE=$(KIT_HOST_TRIPLE)'; \ - } > $@.tmp - @if ! cmp -s $@.tmp $@; then mv $@.tmp $@; else rm -f $@.tmp; fi + } > "$$tmp"; \ + if ! cmp -s "$$tmp" "$@"; then mv "$$tmp" "$@"; else rm -f "$$tmp"; fi # Freestanding objects must not see host SDK/libc headers. Homebrew clang can # also inject a configured sysroot before command-line flags; use diff --git a/mk/test.mk b/mk/test.mk @@ -276,6 +276,7 @@ test-t1-obj: $(ROUNDTRIP_BIN) 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 + @$(T1_LOG) interop env KIT=$(abspath $(BIN)) test/tier1/objlink/interop.sh test-t1-cross: bin @$(T1_LOG) cross env KIT=$(abspath $(BIN)) test/tier1/cross/run.sh diff --git a/test/tier1/cross/run.sh b/test/tier1/cross/run.sh @@ -5,6 +5,7 @@ ROOT="$(cd "$(dirname "$0")/../../.." && pwd)" KIT="${KIT:-$ROOT/build/kit}" HOSTED="$ROOT/scripts/hosted.sh" CASES="$ROOT/test/cross/cases" +KITCHEN="$ROOT/test/tier1/kitchen/cross" WORK="$ROOT/build/test/tier1/cross" SELECTOR="${T1_CROSS_TARGETS:-all}" @@ -134,6 +135,51 @@ android_lane() { 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 + android_shared_lane "$sysroot" +} + +android_shared_lane() { + local sysroot="$1" label=android-aa64:shared dir dep_obj dep_so user_obj user_so + dir="$WORK/android-aa64-shared" + mkdir -p "$dir" + dep_obj="$dir/dep.o" + dep_so="$dir/libt1dep.so" + user_obj="$dir/user.o" + user_so="$dir/libt1user.so" + : "$sysroot" + run_cmd "$label:dep-cc" "$dir/dep-cc.log" \ + "$HOSTED" cc android-aa64 -O1 -fPIC -c "$KITCHEN/shared_dep.c" -o "$dep_obj" || return 0 + run_cmd "$label:dep-so" "$dir/dep-so.log" \ + "$HOSTED" cc android-aa64 -shared "$dep_obj" -o "$dep_so" || return 0 + run_cmd "$label:user-cc" "$dir/user-cc.log" \ + "$HOSTED" cc android-aa64 -O1 -fPIC -c "$KITCHEN/shared_main.c" -o "$user_obj" || return 0 + run_cmd "$label:user-so" "$dir/user-so.log" \ + "$HOSTED" cc android-aa64 -shared "$user_obj" -L "$dir" -lt1dep -o "$user_so" || return 0 + if [ -s "$dep_so" ] && [ -s "$user_so" ]; then kit_pass "$label"; else kit_fail "$label" "shared object missing"; fi +} + +linux_shared_lane() { + local token="$1" label="$1:shared" sysroot dir dep_obj dep_so main_obj exe + match_selector "$token" || return 0 + sysroot="$(hosted_path "$token")" + if [ -z "$sysroot" ] || [ ! -d "$sysroot" ]; then + return 0 + fi + dir="$WORK/$token-shared" + mkdir -p "$dir" + dep_obj="$dir/dep.o" + dep_so="$dir/libt1dep.so" + main_obj="$dir/main.o" + exe="$dir/main" + run_cmd "$label:dep-cc" "$dir/dep-cc.log" \ + "$HOSTED" cc "$token" -O1 -fPIC -c "$KITCHEN/shared_dep.c" -o "$dep_obj" || return 0 + run_cmd "$label:dep-so" "$dir/dep-so.log" \ + "$HOSTED" cc "$token" -shared "$dep_obj" -o "$dep_so" || return 0 + run_cmd "$label:main-cc" "$dir/main-cc.log" \ + "$HOSTED" cc "$token" -O1 -c "$KITCHEN/shared_main.c" -o "$main_obj" || return 0 + run_cmd "$label:main-link" "$dir/main-link.log" \ + "$HOSTED" cc "$token" "$main_obj" -L "$dir" -lt1dep -o "$exe" || return 0 + if [ -s "$dep_so" ] && [ -s "$exe" ]; then kit_pass "$label"; else kit_fail "$label" "shared linked artifact missing"; fi } apple_sdk_path() { @@ -206,8 +252,10 @@ freestanding_lane() { for arch in aa64 x64 rv64; do hosted_lane "linux-glibc-$arch" default + linux_shared_lane "linux-glibc-$arch" hosted_lane "linux-musl-$arch" static hosted_lane "linux-musl-$arch" dynamic + linux_shared_lane "linux-musl-$arch" hosted_lane "freebsd-$arch" static done diff --git a/test/tier1/frontend/run-kitchen.sh b/test/tier1/frontend/run-kitchen.sh @@ -32,6 +32,15 @@ check_rc() { fi } +run_expect_rc() { + local label="$1" + local want="$2" + shift 2 + "$@" >/dev/null 2>&1 + local got=$? + check_rc "$label" "$got" "$want" +} + normalize_tokens() { tr '\n' ' ' < "$1" | tr -s '[:space:]' ' ' | sed -e 's/^ //' -e 's/ $//' } @@ -53,33 +62,56 @@ run_pp() { run_c() { local src="$fixture_root/c_kitchen.c" local expected - local run_rc - local obj="$1/c_kitchen.o" - local dump="$1/c_kitchen.dump" + local obj="$1/c_kitchen.o" dump="$1/c_kitchen.dump" + local exe="$1/c_kitchen.exe" + local emit_c="$1/c_kitchen.emit.c" emit_exe="$1/c_kitchen.emit.exe" + local asm="$1/c_kitchen.s" asm_obj="$1/c_kitchen.s.o" asm_exe="$1/c_kitchen.s.exe" expected=$(expected_rc "$fixture_root/c_kitchen.expected") [ -x "$KIT" ] || { printf 'missing kit binary: %s\n' "$KIT" >&2; return 2; } "$KIT" cc -O0 -c "$src" -o "$obj" "$KIT" objdump -h -t "$obj" > "$dump" grep -Eq '(^|[[:space:]])main($|[[:space:]])' "$dump" - "$KIT" run "$src" - run_rc=$? - check_rc "c/kitchen" "$run_rc" "$expected" + + "$KIT" cc -O0 "$src" -lc -o "$exe" + run_expect_rc "c/kitchen-link-exec" "$expected" "$exe" + + "$KIT" cc --emit=c -O0 "$src" -o "$emit_c" + "${CC:-cc}" "$emit_c" -o "$emit_exe" + run_expect_rc "c/kitchen-emit-c-exec" "$expected" "$emit_exe" + + "$KIT" cc -S -O0 "$src" -o "$asm" + "$KIT" as "$asm" -o "$asm_obj" + "$KIT" cc "$asm_obj" -lc -o "$asm_exe" + run_expect_rc "c/kitchen-emit-s-exec" "$expected" "$asm_exe" + + run_expect_rc "c/kitchen-jit" "$expected" "$KIT" run "$src" } run_toy() { local src="$fixture_root/toy_kitchen.toy" local expected - local run_rc + local exe="$1/toy_kitchen.exe" + local emit_c="$1/toy_kitchen.emit.c" emit_exe="$1/toy_kitchen.emit.exe" + local asm="$1/toy_kitchen.s" asm_obj="$1/toy_kitchen.s.o" asm_exe="$1/toy_kitchen.s.exe" expected=$(expected_rc "$fixture_root/toy_kitchen.expected") [ -x "$KIT" ] || { printf 'missing kit binary: %s\n' "$KIT" >&2; return 2; } - "$KIT" run "$src" - run_rc=$? - check_rc "toy/kitchen-jit" "$run_rc" "$expected" - "$KIT" run --no-jit "$src" - run_rc=$? - check_rc "toy/kitchen-interp" "$run_rc" "$expected" + + "$KIT" cc -O0 "$src" -lc -o "$exe" + run_expect_rc "toy/kitchen-link-exec" "$expected" "$exe" + + "$KIT" cc --emit=c -O0 "$src" -o "$emit_c" + "${CC:-cc}" "$emit_c" -o "$emit_exe" + run_expect_rc "toy/kitchen-emit-c-exec" "$expected" "$emit_exe" + + "$KIT" cc -S -O0 "$src" -o "$asm" + "$KIT" as "$asm" -o "$asm_obj" + "$KIT" cc "$asm_obj" -lc -o "$asm_exe" + run_expect_rc "toy/kitchen-emit-s-exec" "$expected" "$asm_exe" + + run_expect_rc "toy/kitchen-jit" "$expected" "$KIT" run "$src" + run_expect_rc "toy/kitchen-interp" "$expected" "$KIT" run --no-jit "$src" } run_wasm() { diff --git a/test/tier1/kitchen/cross/shared_dep.c b/test/tier1/kitchen/cross/shared_dep.c @@ -0,0 +1,3 @@ +int t1_shared_add(int a, int b) { + return a + b; +} diff --git a/test/tier1/kitchen/cross/shared_main.c b/test/tier1/kitchen/cross/shared_main.c @@ -0,0 +1,5 @@ +int t1_shared_add(int, int); + +int main(void) { + return t1_shared_add(20, 22); +} diff --git a/test/tier1/kitchen/objlink/interop/clang_value.c b/test/tier1/kitchen/objlink/interop/clang_value.c @@ -0,0 +1,3 @@ +int clang_value(void) { + return 42; +} diff --git a/test/tier1/kitchen/objlink/interop/kit_main.c b/test/tier1/kitchen/objlink/interop/kit_main.c @@ -0,0 +1,5 @@ +extern int clang_value(void); + +int main(void) { + return clang_value(); +} diff --git a/test/tier1/manifests/system/debug-dwarf.txt b/test/tier1/manifests/system/debug-dwarf.txt @@ -4,4 +4,4 @@ make:test-dwarf make:test-debug driver:objdump-dwarf/01-dwarf-all driver:dbg/repl-help - +driver:addr2line-symbolize diff --git a/test/tier1/manifests/system/tools.txt b/test/tier1/manifests/system/tools.txt @@ -1,4 +1,8 @@ # Cheap driver-tool Tier 1 sentinel targets. +test-driver-ar +test-driver-cpio test-driver-tools test-driver-strings test-driver-objdump +test-driver-objcopy +test-driver-strip diff --git a/test/tier1/objlink/README.md b/test/tier1/objlink/README.md @@ -11,6 +11,8 @@ Fixtures live under `test/tier1/kitchen/objlink/`: `kit-roundtrip` and compared through the ELF normalizer. - `link/`: a tiny multi-object program linked through `link-exe-runner` with an archive member and `--gc-sections`, then inspected as an executable image. +- `interop/`: a kit-produced object linked by clang/lld when available, and a + clang-produced object linked back through kit. Run all: diff --git a/test/tier1/objlink/interop.sh b/test/tier1/objlink/interop.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +set -u + +ROOT="$(cd "$(dirname "$0")/../../.." && pwd)" +KIT="${KIT:-$ROOT/build/kit}" +KITCHEN="$ROOT/test/tier1/kitchen/objlink/interop" +WORK="$ROOT/build/test/tier1/objlink/interop" + +mkdir -p "$WORK" + +. "$ROOT/test/lib/kit_sh_report.sh" +kit_report_init +KIT_SKIP_IS_FAILURE=0 + +if [ ! -x "$KIT" ]; then + kit_fail "interop/setup" "kit not built at $KIT" + kit_summary test-t1-objlink-interop + kit_exit +fi +if ! command -v clang >/dev/null 2>&1; then + kit_skip "clang-link" "clang not found" + kit_skip "clang-object-kit-link" "clang not found" + kit_summary test-t1-objlink-interop + kit_exit +fi + +run_expect_rc() { + local label="$1" want="$2" exe="$3" + "$exe" >/dev/null 2>&1 + local got=$? + if [ "$got" -eq "$want" ]; then + kit_pass "$label" + else + kit_fail "$label" "expected rc $want, got $got" + fi +} + +run_cmd() { + local label="$1" log="$2" + shift 2 + if "$@" >"$log" 2>&1; then + return 0 + fi + kit_fail "$label" "see $log" + return 1 +} + +kit_obj="$WORK/kit_main.o" +clang_obj="$WORK/clang_value.o" +clang_exe="$WORK/clang_link.exe" +kit_exe="$WORK/kit_link.exe" +clang_probe_c="$WORK/clang_probe.c" +clang_probe_exe="$WORK/clang_probe.exe" +clang_args=() + +case "$(uname -s 2>/dev/null)" in + Darwin) + sdk="$(xcrun --sdk macosx --show-sdk-path 2>/dev/null || true)" + if [ -n "$sdk" ] && [ -d "$sdk" ]; then + clang_args=(-isysroot "$sdk") + fi ;; + Linux) + if command -v ld.lld >/dev/null 2>&1; then + clang_args=(-fuse-ld=lld) + fi ;; +esac + +printf '%s\n' 'int main(void) { return 0; }' > "$clang_probe_c" + +run_cmd "kit-object" "$WORK/kit-object.log" \ + "$KIT" cc -O0 -c "$KITCHEN/kit_main.c" -o "$kit_obj" +run_cmd "clang-object" "$WORK/clang-object.log" \ + clang -O0 -c "$KITCHEN/clang_value.c" -o "$clang_obj" + +if [ -f "$kit_obj" ] && [ -f "$clang_obj" ]; then + if clang "${clang_args[@]}" "$clang_probe_c" -o "$clang_probe_exe" >"$WORK/clang-link-probe.log" 2>&1; then + if run_cmd "clang-link" "$WORK/clang-link.log" \ + clang "${clang_args[@]}" "$kit_obj" "$clang_obj" -o "$clang_exe"; then + run_expect_rc "clang-link-exec" 42 "$clang_exe" + fi + else + kit_skip "clang-link" "host clang cannot link an executable; see $WORK/clang-link-probe.log" + fi + if run_cmd "clang-object-kit-link" "$WORK/kit-link.log" \ + "$KIT" cc "$kit_obj" "$clang_obj" -o "$kit_exe"; then + run_expect_rc "clang-object-kit-link-exec" 42 "$kit_exe" + fi +fi + +kit_summary test-t1-objlink-interop +kit_exit diff --git a/test/tier1/objlink/run.sh b/test/tier1/objlink/run.sh @@ -23,3 +23,4 @@ run_one() { run_one asm "$ROOT/test/tier1/objlink/asm.sh" run_one object "$ROOT/test/tier1/objlink/object.sh" run_one link "$ROOT/test/tier1/objlink/link.sh" +run_one interop "$ROOT/test/tier1/objlink/interop.sh" diff --git a/test/tier1/system/README.md b/test/tier1/system/README.md @@ -10,14 +10,16 @@ tails the captured log. ## Coverage -- `tools.sh` runs existing cheap tool-driver sentinels: `test-driver-tools` - (`xxd`, `cmp`, `hash`, `disas`, `mc`, `compress`, `image`), - `test-driver-strings`, and `test-driver-objdump`. +- `tools.sh` runs existing cheap tool-driver sentinels: `test-driver-ar` + (`ar`, `ranlib`), `test-driver-cpio`, `test-driver-tools` (`xxd`, `cmp`, + `hash`, `sha256sum`, `b2sum`, `crc32`, `disas`, `mc`, `compress`, `image`), + `test-driver-strings`, `test-driver-objdump`, `test-driver-objcopy`, and + `test-driver-strip`. - `runtime-headers.sh` runs `test-rt-headers`, compiling `test/rt/smoke.c` against the runtime headers for the cheap configured target triples. - `debug-dwarf.sh` runs DWARF reader and debug producer unit targets, one - committed `objdump --dwarf` golden, and the lightweight `kit dbg` help - transcript. + committed `objdump --dwarf` golden, the lightweight `kit dbg` help transcript, + and the `addr2line`/`symbolize` backtrace smoke. - `dist.sh` runs the local CAS and package driver suites through `test-driver-cas` and `test-driver-pkg`. diff --git a/test/tier1/system/debug-dwarf.sh b/test/tier1/system/debug-dwarf.sh @@ -61,4 +61,5 @@ run_step test-dwarf make -C "$repo_root" test-dwarf || exit $? run_step test-debug make -C "$repo_root" test-debug || exit $? run_objdump_dwarf || exit $? run_step dbg-repl-help env KIT="$repo_root/build/kit" DBG_CASE=repl-help \ - sh "$repo_root/test/dbg/run.sh" + sh "$repo_root/test/dbg/run.sh" || exit $? +run_step addr2line-symbolize make -C "$repo_root" test-rt-backtrace