From 138f7c52d5d1df84f808c2ac94a63628da0d032e Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 21 Aug 2026 13:20:30 -0500 Subject: [PATCH 1/3] feat(ios): build simulator slice, package as xcframework --- .gitignore | 1 + scripts/ios/build_all.sh | 31 +++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 7474eca..2d51aee 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ android/src/main/jniLibs/ /macos/frostdart.xcframework/ /ios/libfrostdart.a +/ios/frostdart.xcframework/ diff --git a/scripts/ios/build_all.sh b/scripts/ios/build_all.sh index 1654aac..7b6976f 100755 --- a/scripts/ios/build_all.sh +++ b/scripts/ios/build_all.sh @@ -1,19 +1,38 @@ #!/bin/bash set -e -LIB_ROOT=../.. +# Absolute path to the frostdart repo root (this script lives in scripts/ios). +FROSTDART_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" -cd "$LIB_ROOT/src/serai/hrf" || exit +cd "$FROSTDART_ROOT/src/serai/hrf" || exit # cargokit's artifact search uses the Cargo package name verbatim, but cargo # normalizes dashes to underscores in the emitted filename. Rename so cargo's -# output ("libfrostdart.a") and the podspec's vendored_libraries entry agree. +# output ("libfrostdart.a") and the podspec's vendored_frameworks entry agree. # BSD sed (macOS) syntax; idempotent. sed -i '' 's/^name = "hrf-api"$/name = "frostdart"/' Cargo.toml +# Build for both iOS device (aarch64-apple-ios) and the iOS Simulator on +# Apple Silicon (aarch64-apple-ios-sim). Both slices are arm64, so they +# cannot be combined with lipo; they are packaged as an XCFramework instead. export IPHONEOS_DEPLOYMENT_TARGET=15.0 -export RUSTFLAGS="-C link-arg=-mios-version-min=15.0" +export CARGO_TARGET_AARCH64_APPLE_IOS_RUSTFLAGS="-C link-arg=-mios-version-min=15.0" +export CARGO_TARGET_AARCH64_APPLE_IOS_SIM_RUSTFLAGS="-C link-arg=-mios-simulator-version-min=15.0" + cargo build --target aarch64-apple-ios --release --lib +cargo build --target aarch64-apple-ios-sim --release --lib + +DEVICE_LIB="../target/aarch64-apple-ios/release/libfrostdart.a" +SIM_LIB="../target/aarch64-apple-ios-sim/release/libfrostdart.a" +HEADERS_DIR="$FROSTDART_ROOT/src/serai/hrf" + +# Keep the legacy device-only static library next to the podspec for any +# consumers that still reference it directly. +cp "$DEVICE_LIB" "$FROSTDART_ROOT/ios/libfrostdart.a" -cp ../target/aarch64-apple-ios/release/libfrostdart.a \ - "$LIB_ROOT/../ios/libfrostdart.a" +# Package device + simulator slices as an XCFramework. +rm -rf "$FROSTDART_ROOT/ios/frostdart.xcframework" +xcodebuild -create-xcframework \ + -library "$DEVICE_LIB" -headers "$HEADERS_DIR" \ + -library "$SIM_LIB" -headers "$HEADERS_DIR" \ + -output "$FROSTDART_ROOT/ios/frostdart.xcframework" From 2ad80f1e02e228ff880957fea2689787bd33858d Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 21 Aug 2026 13:20:30 -0500 Subject: [PATCH 2/3] feat(ios): vend xcframework in podspec --- ios/frostdart.podspec | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/ios/frostdart.podspec b/ios/frostdart.podspec index c9a8c73..fe645a6 100644 --- a/ios/frostdart.podspec +++ b/ios/frostdart.podspec @@ -22,10 +22,12 @@ Bitcoin wallets. s.source = { :path => '.' } s.source_files = 'Classes/**/*' - # libfrostdart.a is produced by scripts/ios/download.sh (release artifact) - # or scripts/ios/build_all.sh (build from source). Both drop it next to this - # podspec. Consumers must run one of those before `pod install`. - s.vendored_libraries = 'libfrostdart.a' + # frostdart.xcframework is produced by scripts/ios/build_all.sh (build from + # source) or scripts/ios/download.sh (release artifact). Both drop it next + # to this podspec. Consumers must run one of those before `pod install`. + # The XCFramework carries arm64 device and arm64 simulator slices; a plain + # static library cannot hold both. + s.vendored_frameworks = 'frostdart.xcframework' s.dependency 'Flutter' s.platform = :ios, '15.0' @@ -34,7 +36,15 @@ Bitcoin wallets. 'DEFINES_MODULE' => 'YES', # Flutter.framework does not contain a i386 slice. 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386', - 'OTHER_LDFLAGS' => '-force_load ${PODS_TARGET_SRCROOT}/libfrostdart.a', + } + # The Dart side resolves symbols from the process at runtime + # (DynamicLibrary.process()), so the whole archive must be linked into the + # app binary. This must live in user_target_xcconfig (not + # pod_target_xcconfig): CocoaPods only extracts the matching + # device/simulator XCFramework slice into PODS_XCFRAMEWORKS_BUILD_DIR + # while building the user target, after the pod target is built. + s.user_target_xcconfig = { + 'OTHER_LDFLAGS' => '-force_load ${PODS_XCFRAMEWORKS_BUILD_DIR}/frostdart/libfrostdart.a', } s.swift_version = '5.0' end From fb4ae7f57690df8f6ebfdaf79e7c5d23f83b711b Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 21 Aug 2026 13:20:30 -0500 Subject: [PATCH 3/3] chore(ios): wrap device artifact as xcframework in download.sh --- scripts/ios/download.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/ios/download.sh b/scripts/ios/download.sh index 8479eb0..6e1ff4b 100755 --- a/scripts/ios/download.sh +++ b/scripts/ios/download.sh @@ -26,3 +26,13 @@ download_and_verify() { download_and_verify "frostdart-ios-aarch64.a" cp "$TMPDIR/frostdart-ios-aarch64.a" "$LIB_ROOT/ios/libfrostdart.a" + +# Release artifacts are device-only; wrap the device slice in an XCFramework +# so the podspec's vendored_frameworks entry resolves. Simulator consumers +# must build from source with scripts/ios/build_all.sh instead. +FROSTDART_ROOT="$(cd "$LIB_ROOT" && pwd)" +rm -rf "$FROSTDART_ROOT/ios/frostdart.xcframework" +xcodebuild -create-xcframework \ + -library "$FROSTDART_ROOT/ios/libfrostdart.a" \ + -headers "$FROSTDART_ROOT/src/serai/hrf" \ + -output "$FROSTDART_ROOT/ios/frostdart.xcframework"