#!/usr/bin/env bash set -euo pipefail SDK_ID="${SWIFT_WASM_SDK_ID:-swift-6.3.2-RELEASE_wasm}" SWIFT_SELECTOR="${SWIFT_WASM_SWIFT_SELECTOR:-+6.3.2}" swift_command() { if command -v swiftly >/dev/null 2>&1; then swiftly run swift "$@" "$SWIFT_SELECTOR" else swift "$@" fi } if ! swift_command sdk list | grep -qx "$SDK_ID"; then echo "wasm: missing Swift SDK '$SDK_ID'" >&2 echo "wasm: install the SDK or set SWIFT_WASM_SDK_ID" >&2 exit 2 fi # The open-source swift.org toolchain ships the WebAssembly codegen backend; the # Xcode-bundled Apple toolchain does not. Cross-compiling to wasm through the Xcode # toolchain therefore aborts deep inside LLVM ("No available targets are compatible # with triple wasm32-...") with a multi-megabyte stack dump that looks like a code # bug but is purely a wrong-toolchain setup. When we are not going through swiftly, # detect that case up front and fail with an actionable message instead. # # Discriminate by the compiler's self-reported build tag, not its path: both # toolchains print "Apple Swift version X", but the Xcode/Apple build tags it # "(swiftlang-...)" while a swift.org toolchain tags it "(swift-...-RELEASE/SNAPSHOT)". # The self-report is authoritative however `swift` is symlinked or shimmed (a path # check misses a /usr/local/bin/swift that links into Xcode). 'swift # -print-target-info -target wasm32-...' is NOT a usable probe: it succeeds even # without the backend, because the frontend knows the triple and only codegen is gone. if ! command -v swiftly >/dev/null 2>&1; then if swift --version 2>/dev/null | grep -q '(swiftlang-'; then echo "wasm: the active Swift is the Xcode/Apple toolchain, which has no WebAssembly" >&2 echo "wasm: codegen backend, so a wasm cross-compile cannot work here and would crash" >&2 echo "wasm: inside LLVM rather than fail cleanly." >&2 echo "wasm: install swiftly and the swift.org toolchain that matches '$SWIFT_SELECTOR'" >&2 echo "wasm: (it ships the wasm backend), or put a swift.org toolchain first as 'swift'," >&2 echo "wasm: then re-run. See https://www.swift.org/install/ and https://swiftwasm.org." >&2 exit 2 fi fi swift_command build --swift-sdk "$SDK_ID" swift_command build -c release --swift-sdk "$SDK_ID" # Runtime proof (#144): when wasmtime is available, the full test suite # executes on an actual WASI runtime; the first such run caught a real # wasm32 trap (32-bit Int conversion in format-number). Build-only when # wasmtime is absent, with a notice. if command -v wasmtime >/dev/null 2>&1; then swift_command build --build-tests --swift-sdk "$SDK_ID" TEST_BINARY="$(ls .build/wasm32-*/debug/*PackageTests.xctest 2>/dev/null | head -1)" if [ -n "$TEST_BINARY" ]; then wasmtime run --dir . "$TEST_BINARY" --testing-library swift-testing else echo "wasm: test binary not found; skipping runtime execution" >&2 fi else echo "wasm: wasmtime not installed; build-only (install wasmtime for the runtime proof)" >&2 fi