#!/bin/sh set -eu ROOT=$(CDPATH= cd -- "$(dirname "$0")/../.." && pwd) BUILDER="$ROOT/core/scripts/build-xcframework.sh" EXPECTED_EXPORTS='_verse_core_abi_version _verse_core_cancel_v1 _verse_core_connect_v1 _verse_core_create_v1 _verse_core_destroy_v1 _verse_core_request_idr_v1 _verse_core_send_input_v1' test "$(uname -s)" = Darwin test "$(uname -m)" = arm64 test -x "$BUILDER" WORK=$(mktemp -d "${TMPDIR:-/tmp}/versevdi-core-package.XXXXXX") trap 'rm -rf "$WORK"' EXIT HUP INT TERM "$BUILDER" --output "$WORK/one" --target-dir "$WORK/target-one" "$BUILDER" --output "$WORK/two" --target-dir "$WORK/target-two" framework_one="$WORK/one/VerseVDICore.xcframework" framework_two="$WORK/two/VerseVDICore.xcframework" library_one=$(find "$framework_one" -type f -name libversevdi_core.a -print) library_two=$(find "$framework_two" -type f -name libversevdi_core.a -print) test "$(printf '%s\n' "$library_one" | grep -c .)" -eq 1 test "$(printf '%s\n' "$library_two" | grep -c .)" -eq 1 test "$(/usr/libexec/PlistBuddy -c 'Print :AvailableLibraries:0:SupportedPlatform' "$framework_one/Info.plist")" = macos test "$(/usr/libexec/PlistBuddy -c 'Print :AvailableLibraries:0:SupportedArchitectures:0' "$framework_one/Info.plist")" = arm64 test "$(/usr/libexec/PlistBuddy -c 'Print :AvailableLibraries' "$framework_one/Info.plist" | grep -c 'Dict {')" -eq 1 test "$(xcrun lipo -archs "$library_one")" = arm64 file "$library_one" | grep -F 'current ar archive' >/dev/null consumer="$WORK/consumer" xcrun clang \ -arch arm64 \ -mmacosx-version-min=14.0 \ -std=c11 \ -Wall -Wextra -Werror -Wpedantic \ -fmodules \ -fmodules-cache-path="$WORK/module-cache" \ -I"$(dirname "$library_one")/Headers" \ "$ROOT/core/tests/ffi/abi_smoke.c" \ "$library_one" \ -framework Security \ -framework SystemConfiguration \ -framework CoreFoundation \ -lresolv \ -o "$consumer" test "$(xcrun lipo -archs "$consumer")" = arm64 file "$consumer" | grep -F 'Mach-O 64-bit executable arm64' >/dev/null symbols=$(xcrun nm -gjU "$consumer") actual_exports=$(printf '%s\n' "$symbols" | grep '^_verse_core_' | LC_ALL=C sort -u) test "$actual_exports" = "$EXPECTED_EXPORTS" dependencies=$(xcrun otool -L "$consumer") unexpected_dependencies=$(printf '%s\n' "$dependencies" | tail -n +2 | awk '{print $1}' | grep -Ev '^(/usr/lib/(libSystem\.B|libresolv\.9)\.dylib|/System/Library/Frameworks/(CoreFoundation|Security|SystemConfiguration)\.framework/Versions/A/[^/]+)$' || true) test -z "$unexpected_dependencies" "$consumer" i=0 pids= while test "$i" -lt 32; do "$consumer" & pids="$pids $!" i=$((i + 1)) done for pid in $pids; do wait "$pid" done canonical_tree() { ( cd "$1" find . -type f -print | LC_ALL=C sort | while IFS= read -r path; do digest=$(shasum -a 256 "$path" | awk '{print $1}') printf '%s %s\n' "$digest" "$path" done ) } canonical_tree "$framework_one" >"$WORK/one.tree" canonical_tree "$framework_two" >"$WORK/two.tree" cmp "$WORK/one.tree" "$WORK/two.tree" test "$(shasum -a 256 "$library_one" | awk '{print $1}')" = "$(shasum -a 256 "$library_two" | awk '{print $1}')" source_epoch=$(git -C "$ROOT" show -s --format=%ct HEAD) find "$framework_one" -exec stat -f '%m' {} \; | while IFS= read -r epoch; do test "$epoch" = "$source_epoch" done strings "$library_one" >"$WORK/library.strings" if grep -F "$ROOT" "$WORK/library.strings" >/dev/null; then echo "repository path leaked into static archive" >&2 exit 1 fi archive_members=$(xcrun ar -tv "$library_one") printf '%s\n' "$archive_members" | awk '$7 != "1970" { exit 1 }' printf 'framework_sha256=%s\n' "$(shasum -a 256 "$WORK/one.tree" | awk '{print $1}')" printf 'library_sha256=%s\n' "$(shasum -a 256 "$library_one" | awk '{print $1}')"