Vendor the SDK's SwiftPM-only deps as a pre-built static binary#69
Vendor the SDK's SwiftPM-only deps as a pre-built static binary#69peachbits wants to merge 1 commit into
Conversation
|
✅ Validation passed. A full
This is the same artifact set the manual spike built — which builds + runs a ZEC wallet on the simulator. |
af4b872 to
e5bcf7e
Compare
|
The branch has been amended ( |
|
✅ GUI integration validation complete (Edge app, static frameworks, against the regenerated
One integration note for Edge: after |
The modern ZcashLightClientKit SDK pulls grpc-swift (1.24+), SwiftNIO, SwiftProtobuf and SQLite.swift via SwiftPM only -- grpc-swift's CocoaPods releases stopped at 1.8.0, so it can no longer be a CocoaPods dependency. Consuming the SDK via spm_dependency would force the entire host app onto dynamic frameworks. Instead, scripts/buildVendoredDeps.ts pre-builds those leaf dependencies into one Release static lib per platform (device arm64; simulator arm64+x86_64, matching the libzcashlc baseline) plus their Swift/C modules, under ios/vendored/ -- generated by 'npm run update-sources' and shipped in the npm tarball. Dependency versions are pinned to the SDK's Package.resolved (-disableAutomaticPackageResolution). The ZcashLightClientKit source keeps compiling in-pod exactly as before, and the host app stays on static frameworks. The binary .swiftmodule format only loads under the exact Swift compiler that produced it (library-evolution .swiftinterface is unavailable: swift-nio doesn't compile under evolution), so the build stamps ios/vendored/swift-version.txt and the podspec fails fast with rebuild instructions when the consuming Xcode doesn't match. Note: sqlite3 is not part of this binary -- SQLite.swift on Apple platforms links the system sqlite3 module, so there is nothing to exclude. Edge's pre-existing duplicate-sqlite3 ld warnings come from libzcashlc vs libpiratelc (both Rust cores embed sqlite3) and are unrelated to this change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
e5bcf7e to
128a823
Compare
Summary
The modern ZcashLightClientKit SDK pulls grpc-swift (1.24+), SwiftNIO, SwiftProtobuf and SQLite.swift via SwiftPM only — grpc-swift's CocoaPods releases stopped at 1.8.0 — so those can no longer be CocoaPods
dependencys. Consuming the SDK through React Native'sspm_dependencywould force the entire host app onto dynamic frameworks (and, on RN 0.85, an open-ended community-pod link cascade).This vendors just those leaf dependencies as a pre-built static binary instead, so the host app stays on static frameworks and the ZcashLightClientKit source keeps compiling in-pod exactly as it does today.
What changed
scripts/buildVendoredDeps.ts(new): builds the SDK's SwiftPM dependency graph (excluding ZcashLightClientKit itself) in Release config for device (arm64) and simulator (arm64 + x86_64 — same arch baseline aslibzcashlc.xcframework, so Intel Macs still build), merging raw per-target objects per arch andlipo-ing the simulator slices. Harvests the Swift.swiftmodules + Cmodule.modulemaps the in-pod SDK source imports. Dependency versions are pinned to the SDK's ownPackage.resolved(-disableAutomaticPackageResolutionhard-fails on drift). Driven bynpm run update-sources; output is gitignored and shipped in the npm tarball (same model aslibzcashlc.xcframework).react-native-zcash.podspec: drops thegRPC-Swift/SQLite.swiftpod dependencies; vendors the per-platform deps binary via SDK-conditional-force_loadplus the module search paths. Bridge, SDK-source vendoring, checkpoints, andlibzcashlcare unchanged..swiftmodulefiles only load under the exact Swift compiler that produced them (the stable alternative — library-evolution.swiftinterface— is unavailable because swift-nio doesn't compile under evolution). The build stampsios/vendored/swift-version.txt; the podspec fails fast at pod-install time with actionable instructions (npm run update-sourcesrebuilds locally, ~10–15 min) when the consuming Xcode doesn't match. This does mean the published tarball's prebuilt deps are coupled to the publishing Xcode — the guard turns that from a cryptic compile error into a one-command fix..gitignore: treatsios/vendored/as generated.Tradeoff: this deliberately gives up Xcode-agnosticism
Today's package is compiler-agnostic by construction: every Swift line (bridge + vendored SDK source + the gRPC/SQLite pods) compiles from source on the consumer's machine, and the only prebuilt binary (
libzcashlc) sits behind a C interface, which is ABI-stable across all toolchains — any Xcode works. This PR introduces the package's first prebuilt Swift binary, and consuming prebuilt Swift means reading.swiftmodulefiles, a compiler-version-locked format (Swift's machine-code ABI is stable; its module format is not). The portable alternative (library-evolution.swiftinterface) is off the table by swift-nio upstream policy (apple/swift-nio#2470, #2897 — closed "not planned"), so the lock is permanent while NIO is in the SDK's dependency graph.The rejected alternative that would preserve Xcode-agnosticism: vendor the grpc/NIO/SwiftProtobuf source into the pod the way the SDK source is vendored. Rejected because it means hand-maintaining a CocoaPods replica of SwiftPM's ~35-target build graph (including the CNIOBoringSSL C target and per-target module maps) and re-deriving it on every SDK bump. The prebuilt binary trades that permanent maintenance burden for: coupling to the publishing Xcode, mitigated by the stamp/fail-fast guard and a one-command local rebuild. If sustained mixed-Xcode pain ever exceeds that maintenance cost, the revisit levers are (a) source-vendoring the deps, or (b) per-compiler prebuilt variants as GitHub release assets (same download pattern as
libzcashlc).sqlite3 note (correcting an earlier claim)
An earlier revision of this PR claimed it deduplicated sqlite3 symbols. That was a misdiagnosis: SQLite.swift on Apple platforms has no C-shim target (it imports the system
sqlite3clang module), so the deps binary never contained sqlite3 definitions in the first place. The duplicate-sqlite3_*ld warnings visible in Edge builds come fromlibzcashlcvs react-native-piratechain'slibpiratelc(both Rust cores embed sqlite3); they are pre-existing and unrelated to this change.Validation
npm run update-sourcesruns clean end-to-end (SDK clone → libzcashlc → source vendoring → deps build for both platforms)..a= arm64; simulator.a= arm64 + x86_64 (lipo -infoverified);swift-version.txtstamped; GRPC/NIO symbols present; 0 sqlite3 definitions; ZcashLightClientKit correctly absent (compiled from source in-pod).strip -S) is a possible follow-up.Pairs with the GUI's RN 0.85 upgrade: EdgeApp/edge-react-gui#6064
🤖 Generated with Claude Code