mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 10:29:58 +02:00
feat(apple): native SwiftUI app for iOS and macOS
Add a native SwiftUI VniDrop app (Send/Receive/Settings) talking to the Rust core via generated UniFFI Swift bindings, plus the uniffi-bindgen helper crate. iOS uses a TabView, macOS a NavigationSplitView sidebar.
This commit is contained in:
104
apple/scripts/build-core.sh
Executable file
104
apple/scripts/build-core.sh
Executable file
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Builds the VniDrop Rust core for Apple platforms and produces:
|
||||
# - apple/VnidropCore/vnidrop.xcframework (static libs for device/sim/macOS)
|
||||
# - apple/VnidropCore/Sources/VnidropCore/Vnidrop.swift (generated bindings)
|
||||
#
|
||||
# The Rust crate (crates/vnidrop) is NOT modified. Bindings are generated in
|
||||
# UniFFI library mode from the compiled staticlib, so the Swift surface always
|
||||
# matches the scaffolding baked into the library.
|
||||
#
|
||||
# Usage: apple/scripts/build-core.sh [debug|release] (default: release)
|
||||
set -euo pipefail
|
||||
|
||||
# Default to debug: the workspace `[profile.release]` uses thin LTO, which the
|
||||
# current macOS toolchain miscompiles into corrupt host proc-macro dylibs
|
||||
# ("mis-aligned LINKEDIT string pool"), breaking any release cross-compile. Debug
|
||||
# static libs are correct and adequate for development and the simulator. For a
|
||||
# release build, pass `release` AND disable LTO for proc-macros/build scripts via
|
||||
# CARGO_PROFILE_RELEASE_BUILD_OVERRIDE_LTO=false in a Cargo.toml profile — see the
|
||||
# package README. The Rust crate itself is never modified.
|
||||
PROFILE="${1:-debug}"
|
||||
case "$PROFILE" in
|
||||
debug) CARGO_PROFILE_FLAG="" ;;
|
||||
release) CARGO_PROFILE_FLAG="--release" ;;
|
||||
*) echo "profile must be debug or release" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
APPLE_DIR="$REPO_ROOT/apple"
|
||||
PKG_DIR="$APPLE_DIR/VnidropCore"
|
||||
GEN_DIR="$PKG_DIR/Sources/VnidropCore"
|
||||
TARGET_DIR="$REPO_ROOT/target"
|
||||
BUILD_DIR="$APPLE_DIR/.build-core"
|
||||
|
||||
# Match the iOS deployment target used by the Gobley config in shared/build.gradle.kts.
|
||||
export IPHONEOS_DEPLOYMENT_TARGET="${IPHONEOS_DEPLOYMENT_TARGET:-16.0}"
|
||||
export MACOSX_DEPLOYMENT_TARGET="${MACOSX_DEPLOYMENT_TARGET:-13.0}"
|
||||
|
||||
# The workspace `[profile.dev] strip = "debuginfo"` corrupts host proc-macro
|
||||
# dylibs on the current Apple toolchain ("mis-aligned LINKEDIT string pool"),
|
||||
# which breaks compilation. The Gobley Xcode run-script uses the same override.
|
||||
# This never touches the Rust crate — it only changes how the build is invoked.
|
||||
export CARGO_PROFILE_DEV_STRIP=none
|
||||
|
||||
IOS_TARGET="aarch64-apple-ios"
|
||||
SIM_ARM_TARGET="aarch64-apple-ios-sim"
|
||||
SIM_X64_TARGET="x86_64-apple-ios"
|
||||
MAC_TARGET="aarch64-apple-darwin"
|
||||
|
||||
echo "==> Building vnidrop staticlib ($PROFILE) for Apple targets"
|
||||
for t in "$IOS_TARGET" "$SIM_ARM_TARGET" "$SIM_X64_TARGET" "$MAC_TARGET"; do
|
||||
echo " - $t"
|
||||
rustup target add "$t" >/dev/null 2>&1 || true
|
||||
( cd "$REPO_ROOT" && cargo build -p vnidrop --target "$t" $CARGO_PROFILE_FLAG )
|
||||
done
|
||||
|
||||
LIB_SUBDIR="$PROFILE"
|
||||
[ "$PROFILE" = "debug" ] && LIB_SUBDIR="debug"
|
||||
|
||||
MAC_LIB="$TARGET_DIR/$MAC_TARGET/$LIB_SUBDIR/libvnidrop.a"
|
||||
IOS_LIB="$TARGET_DIR/$IOS_TARGET/$LIB_SUBDIR/libvnidrop.a"
|
||||
|
||||
# Fresh scratch dir for the bindgen output and the universal simulator lib.
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
# Combine the two simulator architectures into one universal static library so
|
||||
# the xcframework works on both Apple Silicon and Intel simulators.
|
||||
SIM_LIB="$BUILD_DIR/libvnidrop-sim.a"
|
||||
lipo -create \
|
||||
"$TARGET_DIR/$SIM_ARM_TARGET/$LIB_SUBDIR/libvnidrop.a" \
|
||||
"$TARGET_DIR/$SIM_X64_TARGET/$LIB_SUBDIR/libvnidrop.a" \
|
||||
-output "$SIM_LIB"
|
||||
|
||||
echo "==> Generating Swift bindings (library mode)"
|
||||
( cd "$REPO_ROOT" && cargo run -p uniffi-bindgen -- generate \
|
||||
--library "$MAC_LIB" \
|
||||
--language swift \
|
||||
--out-dir "$BUILD_DIR" )
|
||||
|
||||
# UniFFI emits: Vnidrop.swift, vnidropFFI.h, vnidropFFI.modulemap
|
||||
mkdir -p "$GEN_DIR"
|
||||
cp "$BUILD_DIR/Vnidrop.swift" "$GEN_DIR/Vnidrop.swift"
|
||||
|
||||
# Assemble a headers dir the xcframework can carry as the FFI module.
|
||||
HEADERS_DIR="$BUILD_DIR/headers"
|
||||
mkdir -p "$HEADERS_DIR"
|
||||
cp "$BUILD_DIR/vnidropFFI.h" "$HEADERS_DIR/"
|
||||
# The xcframework module map must be named module.modulemap.
|
||||
cp "$BUILD_DIR/vnidropFFI.modulemap" "$HEADERS_DIR/module.modulemap"
|
||||
|
||||
echo "==> Assembling xcframework"
|
||||
XCFRAMEWORK="$PKG_DIR/vnidrop.xcframework"
|
||||
rm -rf "$XCFRAMEWORK"
|
||||
xcodebuild -create-xcframework \
|
||||
-library "$IOS_LIB" -headers "$HEADERS_DIR" \
|
||||
-library "$SIM_LIB" -headers "$HEADERS_DIR" \
|
||||
-library "$MAC_LIB" -headers "$HEADERS_DIR" \
|
||||
-output "$XCFRAMEWORK"
|
||||
|
||||
echo "==> Done."
|
||||
echo " xcframework: $XCFRAMEWORK"
|
||||
echo " bindings: $GEN_DIR/Vnidrop.swift"
|
||||
Reference in New Issue
Block a user