| 1 | #!/usr/bin/env bash |
| 2 | set -euo pipefail |
| 3 | |
| 4 | ROOT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd) |
| 5 | cd "$ROOT_DIR" |
| 6 | |
| 7 | DIST_DIR="$ROOT_DIR/dist/swift" |
| 8 | PACKAGE_DIR="$DIST_DIR/Package" |
| 9 | HEADERS_DIR="$DIST_DIR/Headers" |
| 10 | FRAMEWORK_DIR="$DIST_DIR/EdFramework.xcframework" |
| 11 | ZIP_PATH="$DIST_DIR/EdFramework.xcframework.zip" |
| 12 | CHECKSUM_PATH="$DIST_DIR/EdFramework.checksum.txt" |
| 13 | VERSION_PATH="$DIST_DIR/version.txt" |
| 14 | BINDGEN="$ROOT_DIR/target/release/uniffi-bindgen" |
| 15 | MANIFEST="$ROOT_DIR/crates/ed-agent-ffi/Cargo.toml" |
| 16 | APPLE_TARGET_DIR="$ROOT_DIR/target/apple" |
| 17 | |
| 18 | IOS_DEPLOYMENT_TARGET="${IOS_DEPLOYMENT_TARGET:-16.0}" |
| 19 | MACOS_DEPLOYMENT_TARGET="${MACOS_DEPLOYMENT_TARGET:-14.0}" |
| 20 | TVOS_DEPLOYMENT_TARGET="${TVOS_DEPLOYMENT_TARGET:-16.0}" |
| 21 | VISIONOS_DEPLOYMENT_TARGET="${VISIONOS_DEPLOYMENT_TARGET:-1.0}" |
| 22 | WATCHOS_DEPLOYMENT_TARGET="${WATCHOS_DEPLOYMENT_TARGET:-9.0}" |
| 23 | |
| 24 | rm -rf "$FRAMEWORK_DIR" "$ZIP_PATH" "$CHECKSUM_PATH" "$VERSION_PATH" "$PACKAGE_DIR" "$HEADERS_DIR" |
| 25 | mkdir -p "$PACKAGE_DIR/Sources/Ed" "$HEADERS_DIR" |
| 26 | |
| 27 | cargo build --manifest-path uniffi-bindgen/Cargo.toml --release |
| 28 | |
| 29 | # Each slice takes 15-20 minutes and cargo never prints the target it is |
| 30 | # building, so a bare `error: could not compile` an hour into the log cannot be |
| 31 | # attributed without counting `Finished` lines. Announce every target. |
| 32 | # |
| 33 | # The tvOS, visionOS and watchOS targets are tier 3: no prebuilt std ships for |
| 34 | # them, hence nightly and -Z build-std. |
| 35 | build_target() { |
| 36 | local target="$1" deployment="$2" |
| 37 | shift 2 |
| 38 | echo "::group::cargo rustc --target $target" |
| 39 | env "$deployment" cargo "$@" rustc \ |
| 40 | --target-dir "$APPLE_TARGET_DIR" \ |
| 41 | --manifest-path "$MANIFEST" \ |
| 42 | --target "$target" \ |
| 43 | --release --lib --crate-type staticlib |
| 44 | echo "::endgroup::" |
| 45 | } |
| 46 | |
| 47 | build_target aarch64-apple-ios "IPHONEOS_DEPLOYMENT_TARGET=$IOS_DEPLOYMENT_TARGET" |
| 48 | build_target aarch64-apple-ios-sim "IPHONEOS_DEPLOYMENT_TARGET=$IOS_DEPLOYMENT_TARGET" |
| 49 | build_target aarch64-apple-darwin "MACOSX_DEPLOYMENT_TARGET=$MACOS_DEPLOYMENT_TARGET" |
| 50 | build_target aarch64-apple-tvos "TVOS_DEPLOYMENT_TARGET=$TVOS_DEPLOYMENT_TARGET" +nightly -Z build-std |
| 51 | build_target aarch64-apple-tvos-sim "TVOS_DEPLOYMENT_TARGET=$TVOS_DEPLOYMENT_TARGET" +nightly -Z build-std |
| 52 | build_target aarch64-apple-visionos "XROS_DEPLOYMENT_TARGET=$VISIONOS_DEPLOYMENT_TARGET" +nightly -Z build-std |
| 53 | build_target aarch64-apple-visionos-sim "XROS_DEPLOYMENT_TARGET=$VISIONOS_DEPLOYMENT_TARGET" +nightly -Z build-std |
| 54 | |
| 55 | "$BINDGEN" generate "$APPLE_TARGET_DIR/aarch64-apple-ios/release/libed_agent_ffi.a" --crate ed_agent_ffi --language swift --out-dir "$PACKAGE_DIR/Sources/Ed" |
| 56 | cp "$PACKAGE_DIR/Sources/Ed/ed_agent_ffiFFI.h" "$HEADERS_DIR/ed_agent_ffiFFI.h" |
| 57 | cp "$PACKAGE_DIR/Sources/Ed/ed_agent_ffiFFI.modulemap" "$HEADERS_DIR/module.modulemap" |
| 58 | |
| 59 | xcodebuild -create-xcframework \ |
| 60 | -library "$APPLE_TARGET_DIR/aarch64-apple-ios/release/libed_agent_ffi.a" -headers "$HEADERS_DIR" \ |
| 61 | -library "$APPLE_TARGET_DIR/aarch64-apple-ios-sim/release/libed_agent_ffi.a" -headers "$HEADERS_DIR" \ |
| 62 | -library "$APPLE_TARGET_DIR/aarch64-apple-tvos/release/libed_agent_ffi.a" -headers "$HEADERS_DIR" \ |
| 63 | -library "$APPLE_TARGET_DIR/aarch64-apple-tvos-sim/release/libed_agent_ffi.a" -headers "$HEADERS_DIR" \ |
| 64 | -library "$APPLE_TARGET_DIR/aarch64-apple-visionos/release/libed_agent_ffi.a" -headers "$HEADERS_DIR" \ |
| 65 | -library "$APPLE_TARGET_DIR/aarch64-apple-visionos-sim/release/libed_agent_ffi.a" -headers "$HEADERS_DIR" \ |
| 66 | -library "$APPLE_TARGET_DIR/aarch64-apple-darwin/release/libed_agent_ffi.a" -headers "$HEADERS_DIR" \ |
| 67 | -output "$FRAMEWORK_DIR" |
| 68 | |
| 69 | export FRAMEWORK_DIR ZIP_PATH |
| 70 | python3 - <<'PY' |
| 71 | import os, stat, zipfile |
| 72 | from pathlib import Path |
| 73 | |
| 74 | root = Path(os.environ["FRAMEWORK_DIR"]) |
| 75 | output = Path(os.environ["ZIP_PATH"]) |
| 76 | with zipfile.ZipFile(output, "w", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as archive: |
| 77 | for path in sorted(item for item in root.rglob("*") if item.is_file()): |
| 78 | info = zipfile.ZipInfo(str(path.relative_to(root.parent)), (1980, 1, 1, 0, 0, 0)) |
| 79 | info.compress_type = zipfile.ZIP_DEFLATED |
| 80 | info.external_attr = (stat.S_IFREG | 0o644) << 16 |
| 81 | archive.writestr(info, path.read_bytes()) |
| 82 | PY |
| 83 | |
| 84 | swift package compute-checksum "$ZIP_PATH" > "$CHECKSUM_PATH" |
| 85 | cargo metadata --no-deps --format-version 1 \ |
| 86 | | python3 -c 'import json,sys; print(next(p["version"] for p in json.load(sys.stdin)["packages"] if p["name"] == "ed-agent"))' \ |
| 87 | > "$VERSION_PATH" |
| 88 | |
| 89 | printf 'XCFramework: %s\nChecksum: %s\nVersion: %s\n' \ |
| 90 | "$FRAMEWORK_DIR" "$(cat "$CHECKSUM_PATH")" "$(cat "$VERSION_PATH")" |