open-standards/wai/wai-sink-swift/scripts/build-xcframework.sh
Transaction Science d264b48689
Some checks failed
wai-audit collector and player integration / does this change touch it (push) Successful in 18s
joule-moq-web browser client / joule-moq-web · does this change touch it (push) Successful in 25s
wai-key-proxy / does this change touch it (push) Successful in 24s
wai-ledger service / does this change touch it (push) Successful in 35s
wai-quantum studio and desktop / does this change touch it (push) Successful in 39s
wai-quantum for JavaScript / does this change touch it (push) Successful in 20s
wai-sink-swift native sink package / does this change touch it (push) Successful in 19s
wai-sink-android native sink library / does this change touch it (push) Successful in 24s
WAI Studio / does this change touch it (push) Successful in 23s
joule-moq-room room service / joule-moq-room · does this change touch it (push) Successful in 7m34s
wai-fleet service / does this change touch it (push) Successful in 10m28s
wai-app and Create / wai-app · does this change touch it (push) Successful in 10m40s
joule-moq-remote host agent / joule-moq-remote · does this change touch it (push) Successful in 10m45s
wai-pack / wai-pack · does this change touch it (push) Successful in 10m13s
wai-ops-gpu integer operators on GPUs / does this change touch it (push) Successful in 10m25s
joule-moq-http live HTTP egress / joule-moq-http · does this change touch it (push) Successful in 10m52s
WAI operation catalogue / does this change touch it (push) Successful in 10m42s
wai-ops-gpu integer operators on GPUs / Vulkan GPUs (framework-128gb) (push) Successful in 11m1s
wai-ops-gpu integer operators on GPUs / Vulkan GPUs (jetson-hub) (push) Successful in 13m26s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Has been cancelled
WAI Studio / Studio in Chromium and Firefox · macos (push) Has been cancelled
WAI Studio / Studio in WebKit · linux (push) Has been cancelled
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Has been cancelled
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Has been cancelled
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Has been cancelled
wai-quantum studio and desktop / studio · browser (push) Has been cancelled
wai-quantum studio and desktop / desktop app · macos (push) Has been cancelled
wai-quantum studio and desktop / desktop app · linux (push) Has been cancelled
wai-quantum studio and desktop / desktop app · windows (push) Has been cancelled
wai-quantum energy-landscape jobs / does this change touch it (push) Has been cancelled
wai-quantum energy-landscape jobs / reader, kernels, answers and the stated result · linux, release (push) Has been cancelled
wai-quantum energy-landscape jobs / the same bits · linux-arm64 (push) Has been cancelled
wai-quantum energy-landscape jobs / the same bits · macos (push) Has been cancelled
wai-quantum energy-landscape jobs / the module under wasm32-wasip2 (wasmtime) (push) Has been cancelled
wai-quantum energy-landscape jobs / native against WebAssembly, over many seeds (push) Has been cancelled
wai-quantum for JavaScript / javascript · linux (push) Has been cancelled
wai-pack / wai-pack · linux (push) Has been cancelled
wai-pack / wai-pack · linux-arm64 (push) Has been cancelled
wai-pack / wai-pack · macos (push) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (push) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (push) Has been cancelled
wai-pack / wai-pack · dependency licences (push) Has been cancelled
wai-ops-gpu integer operators on GPUs / builds · no adapter is not a pass (linux) (push) Has been cancelled
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (push) Has been cancelled
wai-ledger service / service · linux (push) Has been cancelled
wai-ledger service / service · macos (push) Has been cancelled
wai-key-proxy / proxy · linux (push) Has been cancelled
wai-gstreamer / wai-gstreamer · the plugin on a distribution's GStreamer (push) Has been cancelled
wai-fleet service / service · linux (push) Has been cancelled
wai-fleet service / service · macos (push) Has been cancelled
wai-ffmpeg / wai-ffmpeg · the series on FFmpeg 9.0.2, checked and fuzzed (push) Has been cancelled
wai-ffmpeg / wai-ffmpeg · VLC 3.0.24 on the patched FFmpeg, playing the corpora (push) Has been cancelled
WAI examples / WAI examples · does this change touch them (push) Has been cancelled
WAI examples / WAI examples · portable · linux (push) Has been cancelled
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (push) Has been cancelled
WAI examples / WAI examples · android-app · linux-arm64 (push) Has been cancelled
WAI operation catalogue / the catalogue and every door · linux (push) Has been cancelled
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Has been cancelled
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Has been cancelled
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Has been cancelled
wai-audit collector and player integration / collector · linux (push) Has been cancelled
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Has been cancelled
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (push) Has been cancelled
wai-app and Create / wai-app · Create, browser end-to-end (macos) (push) Has been cancelled
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Has been cancelled
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (push) Has been cancelled
joule-moq-room room service / joule-moq-room, every target (push) Has been cancelled
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (push) Has been cancelled
joule-moq-remote host agent / joule-moq-remote, every target (macos) (push) Has been cancelled
joule-moq-http live HTTP egress / joule-moq-http, every target (push) Has been cancelled
Sink wrappers: kiosks named by a roster carry their proofs through Swift, Kotlin and a page
The Swift package's ModelPolicyTests and the Kotlin library's ModelPolicyTest run the model-sink
corpus's kiosks (model-governance §4.5, native-sink §14) through their wrappers: every refused
configuration with its code, each kiosk's decodes their outcomes, each run report carrying the
membership proof its configuration gives for the period's policy, and both periods' bundles
accepted. wai-web's model_gate holds a kiosk page to the same, and the xcframework staging copies
the kiosks' payloads.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-12 04:21:11 -05:00

155 lines
8.5 KiB
Shell
Executable file

#!/usr/bin/env bash
# Build WaiFFI.xcframework: libwai (wai-rs, features `native_sink` and `sink_decode`, no codec
# library) for every target the Swift package supports, with include/wai.h and a module map, into
# ../build/; and stage the native sink corpus, the integer decode's vectors and the model policy
# corpus into the tests' resources.
#
# scripts/build-xcframework.sh every slice
# WAI_SINK_SLICES="macos ios-sim" ... only those (macos, ios, ios-sim, tvos, tvos-sim)
#
# The phone, tablet and desktop targets are tier 2 and build with the repository's pinned
# toolchain (rust-toolchain.toml) once their standard library is installed
# (`rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios x86_64-apple-darwin`).
# The television
# targets are tier 3: their standard library is built from source with the nightly toolchain named
# by WAI_SINK_NIGHTLY (default nightly-2026-10-17), which needs its `rust-src` component; their
# simulator slice is arm64 alone.
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
RS="$HERE/../wai-rs"
OUT="$HERE/build"
TARGET_DIR="${CARGO_TARGET_DIR:-$RS/target}"
SLICES="${WAI_SINK_SLICES:-macos ios ios-sim tvos tvos-sim}"
NIGHTLY="${WAI_SINK_NIGHTLY:-nightly-2026-10-17}"
FEATURES=(--no-default-features --features native_sink,sink_decode)
export MACOSX_DEPLOYMENT_TARGET=13.0 IPHONEOS_DEPLOYMENT_TARGET=16.0 TVOS_DEPLOYMENT_TARGET=16.0
build() { # <target> [nightly]
if [ "${2:-}" = nightly ]; then
cargo "+$NIGHTLY" build --release --locked "${FEATURES[@]}" --lib --manifest-path "$RS/Cargo.toml" \
--target "$1" -Zbuild-std=std,panic_abort
else
cargo build --release --locked "${FEATURES[@]}" --lib --manifest-path "$RS/Cargo.toml" --target "$1"
fi
}
lib() { echo "$TARGET_DIR/$1/release/libwai.a"; }
rm -rf "$OUT/WaiFFI.xcframework" "$OUT/headers" "$OUT/lib"
mkdir -p "$OUT/headers" "$OUT/lib"
cp "$RS/include/wai.h" "$OUT/headers/wai.h"
cat > "$OUT/headers/module.modulemap" <<'MAP'
module WaiFFI {
header "wai.h"
export *
}
MAP
args=()
for s in $SLICES; do
case "$s" in
macos)
build aarch64-apple-darwin; build x86_64-apple-darwin
mkdir -p "$OUT/lib/macos"
lipo -create "$(lib aarch64-apple-darwin)" "$(lib x86_64-apple-darwin)" -output "$OUT/lib/macos/libwai.a"
args+=(-library "$OUT/lib/macos/libwai.a" -headers "$OUT/headers") ;;
ios)
build aarch64-apple-ios
args+=(-library "$(lib aarch64-apple-ios)" -headers "$OUT/headers") ;;
ios-sim)
build aarch64-apple-ios-sim; build x86_64-apple-ios
mkdir -p "$OUT/lib/ios-sim"
lipo -create "$(lib aarch64-apple-ios-sim)" "$(lib x86_64-apple-ios)" -output "$OUT/lib/ios-sim/libwai.a"
args+=(-library "$OUT/lib/ios-sim/libwai.a" -headers "$OUT/headers") ;;
tvos)
build aarch64-apple-tvos nightly
args+=(-library "$(lib aarch64-apple-tvos)" -headers "$OUT/headers") ;;
tvos-sim)
build aarch64-apple-tvos-sim nightly
args+=(-library "$(lib aarch64-apple-tvos-sim)" -headers "$OUT/headers") ;;
*) echo "build-xcframework: unknown slice $s" >&2; exit 2 ;;
esac
done
xcodebuild -create-xcframework "${args[@]}" -output "$OUT/WaiFFI.xcframework"
# The corpus the tests read, staged into their bundle's resources so a test run on a device, where
# the repository is not, reads it too.
cp "$HERE/../live-conformance/native-sink/vectors.json" "$HERE/Tests/WaiSinkTests/Resources/vectors.json"
# The integer decode's vectors (native-sink §13): one or more of each integer capability, with its
# set, so the tests decode them with the device's GPU on a device too.
INT="$HERE/Tests/WaiSinkTests/Resources/int"
V="$HERE/../wai-rs/tests/vectors"
rm -rf "$INT"
mkdir -p "$INT"
for f in int_hyper/tiny_bitstream.wih1 int_hyper/tiny_entropy.json int_hyper/tiny_g_s.bin int_hyper/tiny_h_s.bin \
int_hyper/leaves_bitstream.wih1 int_hyper/leaves_entropy.json int_hyper/leaves_g_s.bin int_hyper/leaves_h_s.bin \
int_video/video_nk_bitstream.wiv1 int_video/video_real_bitstream.wiv1 int_audio/audio_bitstream.wia1 \
int_audio/audio_model.bin int_splat/splat.wis1 int_splat/splat_gs.bin int_mlicpp/stream.wai int_mlicpp/model.wmb \
int_cond/clip.wic1 int_cond/model.wcb; do
cp "$V/$f" "$INT/$(echo "$f" | tr / _)"
done
cp "$HERE/../neural-conformance/vectors/photo/latent.bin" "$INT/photo_latent.bin"
cp "$HERE/../neural-conformance/vectors/photo/int_synth.json" "$INT/photo_int_synth.json"
cat > "$INT/cases.json" <<'CASES'
[
{"capability": "wai.neural.int_hyper", "name": "tiny", "payload": "int_hyper_tiny_bitstream.wih1",
"set": {"entropy.json": "int_hyper_tiny_entropy.json", "g_s.whm": "int_hyper_tiny_g_s.bin", "h_s.whm": "int_hyper_tiny_h_s.bin"}},
{"capability": "wai.neural.int_hyper", "name": "leaves", "payload": "int_hyper_leaves_bitstream.wih1",
"set": {"entropy.json": "int_hyper_leaves_entropy.json", "g_s.whm": "int_hyper_leaves_g_s.bin", "h_s.whm": "int_hyper_leaves_h_s.bin"}},
{"capability": "wai.video.int_hyper", "name": "video_nk", "payload": "int_video_video_nk_bitstream.wiv1",
"set": {"entropy.json": "int_hyper_tiny_entropy.json", "g_s.whm": "int_hyper_tiny_g_s.bin", "h_s.whm": "int_hyper_tiny_h_s.bin"}},
{"capability": "wai.video.int_motion", "name": "video_real", "payload": "int_video_video_real_bitstream.wiv1", "set": {}},
{"capability": "wai.audio.int_codec", "name": "audio", "payload": "int_audio_audio_bitstream.wia1", "set": {"model.wam": "int_audio_audio_model.bin"}},
{"capability": "wai.splat.int_codec", "name": "splat", "payload": "int_splat_splat.wis1", "set": {"g_s.whm": "int_splat_splat_gs.bin"}},
{"capability": "wai.neural.int_synth", "name": "photo", "payload": "photo_latent.bin", "set": {"int_synth.json": "photo_int_synth.json"}},
{"capability": "wai.neural.int_mlicpp", "name": "int_mlicpp", "envelope": "int_mlicpp_stream.wai", "set": {"model.wmb": "int_mlicpp_model.wmb"}},
{"capability": "wai.video.int_cond", "name": "clip", "payload": "int_cond_clip.wic1", "set": {"model.wcb": "int_cond_model.wcb"}}
]
CASES
# The integer frame forms (native-sink §13.6): a stream of each, its objects in order, its set, and
# each frame's SHA-256 (frames.json).
python3 -I - "$HERE/.." "$INT" <<'FRAMES'
import hashlib, json, shutil, sys
wai, out = sys.argv[1], sys.argv[2]
fs = json.load(open(f"{wai}/int-payload-conformance/frame-stream/index.json"))
ic = json.load(open(f"{wai}/int-payload-conformance/int-cond/index.json"))
cases = []
for index, name, common in [(fs, "int_video", None), (fs, "video_nk", None), (ic, "clip", ic["set"])]:
s = next(x for x in index["streams"] if x["name"] == name)
members = {}
for member, rel in (common if common is not None else s["set"]).items():
f = f"frames_{name}_set_{member}"
shutil.copyfile(f"{wai}/{rel}", f"{out}/{f}")
members[member] = f
# A pin in the form `wai.prior.set` covers the set's listing (SPEC §3.1), which the host holds.
listing = None
if common is None and members:
listing = f"frames_{name}_listing"
lines = sorted((m, hashlib.sha256(open(f"{out}/{f}", "rb").read()).hexdigest()) for m, f in members.items())
open(f"{out}/{listing}", "wb").write("".join(f"{d} {m}\n" for m, d in lines).encode())
objects = []
for i, o in enumerate(s["objects"]):
f = f"frames_{name}_{i:02}.wai"
shutil.copyfile(f"{wai}/{o['envelope']}", f"{out}/{f}")
objects.append({"envelope": f, "frame_sha256": o["frame_sha256"]})
cases.append({"capability": s["capability"], "name": name, "set": members, "listing": listing, "objects": objects})
json.dump(cases, open(f"{out}/frames.json", "w"), indent=1)
FRAMES
# A sink that holds a model policy (native-sink §14): the corpus live-conformance/model-sink/, and
# every file its cases read, beside it under its path relative to wai/ with each `/` written `_`.
MODEL="$HERE/Tests/WaiSinkTests/Resources/model"
rm -rf "$MODEL"
mkdir -p "$MODEL"
python3 -I - "$HERE/.." "$MODEL" <<'MODEL'
import json, shutil, sys
wai, out = sys.argv[1], sys.argv[2]
doc = json.load(open(f"{wai}/live-conformance/model-sink/cases.json"))
paths = set()
for s in doc["sets"]:
paths.update(s["files"].values())
for c in doc["decode_cases"] + doc["roster"]["decode_cases"]:
paths.update(p for p in (c["decode"]["payload"], c["decode"]["envelope"]) if p)
for c in doc["frame_cases"]:
paths.update(c["frames"]["objects"])
for p in sorted(paths):
shutil.copyfile(f"{wai}/{p}", f"{out}/{p.replace('/', '_')}")
shutil.copyfile(f"{wai}/live-conformance/model-sink/cases.json", f"{out}/cases.json")
MODEL
echo "wrote $OUT/WaiFFI.xcframework ($SLICES)"