Simplify Rust build for iOS (#1404)

This commit is contained in:
Leendert de Borst
2026-01-02 16:24:46 +01:00
parent eae1daa74e
commit f60cd1cb2a
5 changed files with 117 additions and 366 deletions

View File

@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 60;
objectVersion = 70;
objects = {
/* Begin PBXBuildFile section */
@@ -1275,10 +1275,7 @@
PRODUCT_BUNDLE_IDENTIFIER = net.aliasvault.app;
PRODUCT_NAME = AliasVault;
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_INCLUDE_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/include",
);
SWIFT_INCLUDE_PATHS = "$(inherited) $(PROJECT_DIR)/VaultStoreKit/RustCore/include";
SWIFT_OBJC_BRIDGING_HEADER = "AliasVault/AliasVault-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
@@ -1314,10 +1311,7 @@
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
PRODUCT_BUNDLE_IDENTIFIER = net.aliasvault.app;
PRODUCT_NAME = AliasVault;
SWIFT_INCLUDE_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/include",
);
SWIFT_INCLUDE_PATHS = "$(inherited) $(PROJECT_DIR)/VaultStoreKit/RustCore/include";
SWIFT_OBJC_BRIDGING_HEADER = "AliasVault/AliasVault-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -1644,6 +1638,10 @@
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/include",
);
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
@@ -1652,13 +1650,11 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/include",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/lib/$(RUST_LIB_PLATFORM)",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/lib/device",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/lib/simulator",
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 1.0;
@@ -1678,10 +1674,7 @@
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_INCLUDE_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/include",
);
SWIFT_INCLUDE_PATHS = "$(inherited) $(PROJECT_DIR)/VaultStoreKit/RustCore/include";
SWIFT_INSTALL_MODULE = YES;
SWIFT_INSTALL_OBJC_HEADER = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -1715,6 +1708,10 @@
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/include",
);
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
@@ -1723,13 +1720,11 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/include",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/lib/$(RUST_LIB_PLATFORM)",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/lib/device",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/lib/simulator",
);
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 1.0;
@@ -1748,10 +1743,7 @@
SKIP_INSTALL = YES;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_INCLUDE_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/include",
);
SWIFT_INCLUDE_PATHS = "$(inherited) $(PROJECT_DIR)/VaultStoreKit/RustCore/include";
SWIFT_INSTALL_MODULE = YES;
SWIFT_INSTALL_OBJC_HEADER = NO;
SWIFT_VERSION = 5.0;
@@ -2070,10 +2062,7 @@
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_INCLUDE_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/include",
);
SWIFT_INCLUDE_PATHS = "$(inherited) $(PROJECT_DIR)/VaultStoreKit/RustCore/include";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -2118,10 +2107,7 @@
SKIP_INSTALL = YES;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_INCLUDE_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/VaultStoreKit/RustCore/include",
);
SWIFT_INCLUDE_PATHS = "$(inherited) $(PROJECT_DIR)/VaultStoreKit/RustCore/include";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};

View File

@@ -1,206 +1,51 @@
#!/bin/bash
# Build Rust Core for iOS and output static libraries
# This script is designed to be called from Xcode build phases
# Thin wrapper that calls the main Rust core build script
# This is called by Xcode build phases
#
# Usage:
# ./build-rust-core.sh [--force] [--release]
# ./build-rust-core.sh [--force] [--release|--debug]
#
# Options:
# --force Force rebuild even if sources haven't changed
# --release Build release configuration (default for non-Debug builds)
# The main build script lives at: /core/rust/build.sh
set -e
# Ensure cargo is in PATH (for Xcode build phases)
export PATH="$HOME/.cargo/bin:/usr/local/bin:/opt/homebrew/bin:$PATH"
# Colors for output (only if terminal supports it)
if [ -t 1 ]; then
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
else
RED=''
GREEN=''
YELLOW=''
BLUE=''
NC=''
fi
# Script location and paths
# Script location
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
IOS_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
RUST_CORE_DIR="$(cd "$IOS_DIR/../../../core/rust" && pwd)"
RUST_CORE_DIR="$(cd "$SCRIPT_DIR/../../../../core/rust" && pwd)"
# Output directories - separate device and simulator libraries
RUST_CORE_OUTPUT="$IOS_DIR/VaultStoreKit/RustCore"
DEVICE_LIB_OUTPUT="$RUST_CORE_OUTPUT/lib/device"
SIMULATOR_LIB_OUTPUT="$RUST_CORE_OUTPUT/lib/simulator"
HEADERS_OUTPUT="$RUST_CORE_OUTPUT/include"
SWIFT_BINDINGS_OUTPUT="$RUST_CORE_OUTPUT/Generated"
# Parse arguments
FORCE_BUILD=false
BUILD_RELEASE=true
# Parse arguments to pass through
EXTRA_ARGS=""
FORCE_FLAG=""
# Check Xcode environment for configuration
if [ "${CONFIGURATION:-}" = "Debug" ]; then
BUILD_RELEASE=false
EXTRA_ARGS="--fast"
fi
while [[ $# -gt 0 ]]; do
case $1 in
--force)
FORCE_BUILD=true
FORCE_FLAG="--force"
shift
;;
--release)
BUILD_RELEASE=true
EXTRA_ARGS=""
shift
;;
--debug)
BUILD_RELEASE=false
EXTRA_ARGS="--fast"
shift
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
exit 1
shift
;;
esac
done
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE} Building Rust Core for iOS${NC}"
echo -e "${BLUE}========================================${NC}"
# Check for Rust toolchain
if ! command -v rustc &> /dev/null; then
echo -e "${RED}Error: Rust is not installed${NC}"
echo "Install Rust from https://rustup.rs"
exit 1
fi
if ! command -v cargo &> /dev/null; then
echo -e "${RED}Error: Cargo is not installed${NC}"
exit 1
fi
# Check if rebuild is needed
CHECKSUM_FILE="$RUST_CORE_OUTPUT/.rust-core-checksum"
CURRENT_CHECKSUM=""
if [ -d "$RUST_CORE_DIR/src" ]; then
# Calculate checksum of Rust source files and Cargo.toml
CURRENT_CHECKSUM=$(find "$RUST_CORE_DIR/src" -name "*.rs" -type f -exec md5 -q {} \; 2>/dev/null | md5 -q || echo "unknown")
fi
if [ "$FORCE_BUILD" = false ] && [ -f "$CHECKSUM_FILE" ] && [ -f "$DEVICE_LIB_OUTPUT/libaliasvault_core.a" ]; then
STORED_CHECKSUM=$(cat "$CHECKSUM_FILE" 2>/dev/null || echo "")
if [ "$CURRENT_CHECKSUM" = "$STORED_CHECKSUM" ]; then
echo -e "${GREEN}Rust Core is up to date, skipping build${NC}"
exit 0
fi
fi
echo -e "${YELLOW}Rust source changed, rebuilding...${NC}"
# Determine build profile
if [ "$BUILD_RELEASE" = true ]; then
CARGO_FLAGS="--release"
CARGO_PROFILE="release"
echo -e " Build mode: ${GREEN}Release${NC}"
else
CARGO_FLAGS=""
CARGO_PROFILE="debug"
echo -e " Build mode: ${YELLOW}Debug${NC}"
fi
# Call the main build script with incremental mode
cd "$RUST_CORE_DIR"
# Ensure iOS targets are installed
echo -e "${YELLOW}Checking iOS build targets...${NC}"
for target in aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios; do
if ! rustup target list --installed 2>/dev/null | grep -q "$target"; then
echo -e " Installing $target..."
rustup target add "$target"
fi
done
# Create output directories
mkdir -p "$DEVICE_LIB_OUTPUT" "$SIMULATOR_LIB_OUTPUT" "$HEADERS_OUTPUT" "$SWIFT_BINDINGS_OUTPUT"
# Create temp directory for intermediate files
TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT
# Build for iOS device (arm64)
echo -e "${YELLOW}Building for iOS device (aarch64-apple-ios)...${NC}"
cargo build $CARGO_FLAGS --target aarch64-apple-ios --features uniffi
# Build for iOS simulator (arm64 - Apple Silicon)
echo -e "${YELLOW}Building for iOS simulator arm64...${NC}"
cargo build $CARGO_FLAGS --target aarch64-apple-ios-sim --features uniffi
# Build for iOS simulator (x86_64 - Intel Macs)
echo -e "${YELLOW}Building for iOS simulator x86_64...${NC}"
cargo build $CARGO_FLAGS --target x86_64-apple-ios --features uniffi
# Copy device library
cp "target/aarch64-apple-ios/$CARGO_PROFILE/libaliasvault_core.a" "$DEVICE_LIB_OUTPUT/"
# Create universal simulator library
echo -e "${YELLOW}Creating universal simulator library...${NC}"
lipo -create \
"target/aarch64-apple-ios-sim/$CARGO_PROFILE/libaliasvault_core.a" \
"target/x86_64-apple-ios/$CARGO_PROFILE/libaliasvault_core.a" \
-output "$SIMULATOR_LIB_OUTPUT/libaliasvault_core.a"
# Strip debug symbols in release mode
if [ "$BUILD_RELEASE" = true ]; then
echo -e "${YELLOW}Stripping debug symbols...${NC}"
strip -S "$DEVICE_LIB_OUTPUT/libaliasvault_core.a" 2>/dev/null || true
strip -S "$SIMULATOR_LIB_OUTPUT/libaliasvault_core.a" 2>/dev/null || true
fi
# Generate Swift bindings
echo -e "${YELLOW}Generating Swift bindings...${NC}"
cargo run $CARGO_FLAGS --features uniffi-cli --bin uniffi-bindgen -- generate \
--library "target/aarch64-apple-ios/$CARGO_PROFILE/libaliasvault_core.a" \
--language swift \
--out-dir "$TEMP_DIR"
# Copy headers
cp "$TEMP_DIR/aliasvault_coreFFI.h" "$HEADERS_OUTPUT/"
# Create module.modulemap for the C header
# Note: Module name must match what UniFFI generates in Swift: aliasvault_coreFFI
cat > "$HEADERS_OUTPUT/module.modulemap" << 'EOF'
module aliasvault_coreFFI {
header "aliasvault_coreFFI.h"
export *
}
EOF
# Copy Swift bindings
cp "$TEMP_DIR/aliasvault_core.swift" "$SWIFT_BINDINGS_OUTPUT/"
echo -e "${GREEN}Swift bindings copied to: $SWIFT_BINDINGS_OUTPUT${NC}"
# Store checksum for incremental builds
echo "$CURRENT_CHECKSUM" > "$CHECKSUM_FILE"
# Show sizes
DEVICE_SIZE=$(ls -lh "$DEVICE_LIB_OUTPUT/libaliasvault_core.a" 2>/dev/null | awk '{print $5}' || echo "N/A")
SIM_SIZE=$(ls -lh "$SIMULATOR_LIB_OUTPUT/libaliasvault_core.a" 2>/dev/null | awk '{print $5}' || echo "N/A")
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} Build Complete!${NC}"
echo -e "${GREEN}========================================${NC}"
echo -e " Device library: ${YELLOW}$DEVICE_SIZE${NC}"
echo -e " Simulator library: ${YELLOW}$SIM_SIZE${NC}"
echo -e " Output: ${YELLOW}$RUST_CORE_OUTPUT${NC}"
echo ""
exec ./build.sh --ios --incremental $FORCE_FLAG $EXTRA_ARGS

124
core/rust/Cargo.lock generated
View File

@@ -16,15 +16,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "0.6.21"
@@ -190,16 +181,6 @@ dependencies = [
"thiserror",
]
[[package]]
name = "cc"
version = "1.2.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215"
dependencies = [
"find-msvc-tools",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
@@ -212,12 +193,8 @@ version = "0.4.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
dependencies = [
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
"windows-link",
]
[[package]]
@@ -276,18 +253,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "find-msvc-tools"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844"
[[package]]
name = "fs-err"
version = "2.11.0"
@@ -320,30 +285,6 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "iana-time-zone"
version = "0.1.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.2"
@@ -366,12 +307,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.178"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
[[package]]
name = "log"
version = "0.4.29"
@@ -563,12 +498,6 @@ dependencies = [
"serde_core",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "siphasher"
version = "0.3.11"
@@ -844,65 +773,12 @@ dependencies = [
"nom",
]
[[package]]
name = "windows-core"
version = "0.62.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-implement"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.59.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-result"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-sys"
version = "0.61.2"

View File

@@ -30,8 +30,8 @@ ffi = []
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
# Date/time handling for LWW comparison
chrono = { version = "0.4", features = ["serde"] }
# Date/time handling for LWW comparison (minimal features for smaller binary)
chrono = { version = "0.4", default-features = false, features = ["serde", "now"] }
# Error handling
thiserror = "1.0"
@@ -68,7 +68,7 @@ incremental = true
# Release profile - optimized for size
[profile.release]
opt-level = "z"
lto = true
lto = "fat"
codegen-units = 1
panic = "abort"
strip = true
strip = "symbols"

View File

@@ -57,6 +57,8 @@ BUILD_DOTNET=false
BUILD_IOS=false
BUILD_ANDROID=false
FAST_MODE=false
INCREMENTAL=false
FORCE_BUILD=false
# Parse arguments
while [[ $# -gt 0 ]]; do
@@ -94,19 +96,29 @@ while [[ $# -gt 0 ]]; do
echo -e "${YELLOW}Fast/dev mode enabled${NC}"
shift
;;
--incremental)
INCREMENTAL=true
shift
;;
--force)
FORCE_BUILD=true
shift
;;
--help)
echo "Usage: $0 [options]"
echo ""
echo "Target options:"
echo " --browser Build WASM for browser extension and Blazor WASM client"
echo " --dotnet Build native library for .NET server-side use (macOS/Linux/Windows)"
echo " --ios Build for iOS (device + simulator) with Swift bindings"
echo " --ios Build for iOS (device + simulator arm64) with Swift bindings"
echo " --android Build for Android (arm64-v8a, armeabi-v7a, x86_64) with Kotlin bindings"
echo " --mobile Build for both iOS and Android"
echo " --all Build all targets"
echo ""
echo "Speed options:"
echo " --fast, --dev Faster builds (for development)"
echo " --incremental Skip build if sources unchanged (for Xcode build phases)"
echo " --force Force rebuild even with --incremental"
echo ""
echo "Other options:"
echo " --help Show this help message"
@@ -296,7 +308,7 @@ build_dotnet() {
}
# ============================================
# iOS Build (Universal Binary + Swift Bindings)
# iOS Build (ARM64 only - device + simulator)
# ============================================
build_ios() {
echo ""
@@ -311,9 +323,26 @@ build_ios() {
exit 1
fi
# Install iOS targets if needed
# Incremental build check
local checksum_file="$IOS_APP_DIST/.rust-core-checksum"
local current_checksum=""
if [ -d "$SCRIPT_DIR/src" ]; then
current_checksum=$(find "$SCRIPT_DIR/src" -name "*.rs" -type f -exec md5 -q {} \; 2>/dev/null | md5 -q || echo "unknown")
fi
if $INCREMENTAL && [ "$FORCE_BUILD" = false ] && [ -f "$checksum_file" ] && [ -f "$IOS_APP_DIST/lib/device/libaliasvault_core.a" ]; then
local stored_checksum=$(cat "$checksum_file" 2>/dev/null || echo "")
if [ "$current_checksum" = "$stored_checksum" ]; then
echo -e "${GREEN}Rust Core is up to date, skipping build${NC}"
IOS_BUILD_SKIPPED=true
return 0
fi
fi
IOS_BUILD_SKIPPED=false
# Install iOS targets if needed (ARM64 only - no Intel simulator support)
echo -e " Checking iOS build targets..."
for target in aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios; do
for target in aarch64-apple-ios aarch64-apple-ios-sim; do
if ! rustup target list --installed 2>/dev/null | grep -q "$target"; then
echo -e " Installing $target..."
rustup target add "$target"
@@ -339,23 +368,13 @@ build_ios() {
echo -e " Building for iOS device (aarch64-apple-ios)..."
cargo build $cargo_flags --target aarch64-apple-ios --features uniffi
# Build for iOS simulator (arm64 - Apple Silicon)
# Build for iOS simulator (arm64 - Apple Silicon only)
echo -e " Building for iOS simulator arm64 (aarch64-apple-ios-sim)..."
cargo build $cargo_flags --target aarch64-apple-ios-sim --features uniffi
# Build for iOS simulator (x86_64 - Intel Macs)
echo -e " Building for iOS simulator x86_64 (x86_64-apple-ios)..."
cargo build $cargo_flags --target x86_64-apple-ios --features uniffi
# Copy device library
# Copy libraries (no lipo needed - single architecture for simulator)
cp "target/aarch64-apple-ios/$cargo_profile/libaliasvault_core.a" "$IOS_DIR/device/"
# Create universal simulator library (arm64 + x86_64)
echo -e " Creating universal simulator library..."
lipo -create \
"target/aarch64-apple-ios-sim/$cargo_profile/libaliasvault_core.a" \
"target/x86_64-apple-ios/$cargo_profile/libaliasvault_core.a" \
-output "$IOS_DIR/simulator/libaliasvault_core.a"
cp "target/aarch64-apple-ios-sim/$cargo_profile/libaliasvault_core.a" "$IOS_DIR/simulator/"
# Strip debug symbols from static libraries to reduce size
# Note: -S strips debug symbols but keeps the symbol table needed for linking
@@ -398,29 +417,47 @@ distribute_ios() {
echo ""
echo -e "${BLUE}Distributing to iOS app...${NC}"
mkdir -p "$IOS_APP_DIST/device"
mkdir -p "$IOS_APP_DIST/simulator"
mkdir -p "$IOS_APP_DIST/swift"
mkdir -p "$IOS_APP_DIST/lib/device"
mkdir -p "$IOS_APP_DIST/lib/simulator"
mkdir -p "$IOS_APP_DIST/include"
mkdir -p "$IOS_APP_DIST/Generated"
# Copy libraries
if [ -f "$IOS_DIR/device/libaliasvault_core.a" ]; then
cp "$IOS_DIR/device/libaliasvault_core.a" "$IOS_APP_DIST/device/"
cp "$IOS_DIR/device/libaliasvault_core.a" "$IOS_APP_DIST/lib/device/"
echo -e " Copied device library"
fi
if [ -f "$IOS_DIR/simulator/libaliasvault_core.a" ]; then
cp "$IOS_DIR/simulator/libaliasvault_core.a" "$IOS_APP_DIST/simulator/"
cp "$IOS_DIR/simulator/libaliasvault_core.a" "$IOS_APP_DIST/lib/simulator/"
echo -e " Copied simulator library"
fi
# Copy Swift bindings
# Copy headers and modulemap
if [ -d "$IOS_DIR/swift" ] && [ -n "$(ls -A "$IOS_DIR/swift" 2>/dev/null)" ]; then
cp "$IOS_DIR/swift"/*.swift "$IOS_APP_DIST/swift/" 2>/dev/null || true
cp "$IOS_DIR/swift"/*.h "$IOS_APP_DIST/swift/" 2>/dev/null || true
cp "$IOS_DIR/swift"/*.modulemap "$IOS_APP_DIST/swift/" 2>/dev/null || true
cp "$IOS_DIR/swift"/*.h "$IOS_APP_DIST/include/" 2>/dev/null || true
# Create module.modulemap for the C header
cat > "$IOS_APP_DIST/include/module.modulemap" << 'EOF'
module aliasvault_coreFFI {
header "aliasvault_coreFFI.h"
export *
}
EOF
echo -e " Copied headers and modulemap"
# Copy Swift bindings
cp "$IOS_DIR/swift"/*.swift "$IOS_APP_DIST/Generated/" 2>/dev/null || true
echo -e " Copied Swift bindings"
fi
# Save checksum for incremental builds
local current_checksum=""
if [ -d "$SCRIPT_DIR/src" ]; then
current_checksum=$(find "$SCRIPT_DIR/src" -name "*.rs" -type f -exec md5 -q {} \; 2>/dev/null | md5 -q || echo "unknown")
fi
echo "$current_checksum" > "$IOS_APP_DIST/.rust-core-checksum"
# Create README
cat > "$IOS_APP_DIST/README.md" << 'README_EOF'
# Rust Core iOS Library
@@ -429,9 +466,10 @@ Auto-generated from `/core/rust`. Do not edit manually.
## Contents
- `device/libaliasvault_core.a` - Static library for iOS devices (arm64)
- `simulator/libaliasvault_core.a` - Universal static library for iOS simulator (arm64 + x86_64)
- `swift/` - Swift bindings generated by UniFFI
- `lib/device/libaliasvault_core.a` - Static library for iOS devices (arm64)
- `lib/simulator/libaliasvault_core.a` - Static library for iOS simulator (arm64 Apple Silicon)
- `include/` - C headers and modulemap for UniFFI bindings
- `Generated/` - Swift bindings generated by UniFFI
## Regenerate
@@ -440,11 +478,14 @@ cd /core/rust
./build.sh --ios
```
## Integration
## Xcode Integration
1. Add the static library to your Xcode project
2. Add the Swift bindings to your project
3. Import `aliasvault_core` in your Swift code
The library is automatically built by the Xcode build phase which calls:
```bash
../../core/rust/build.sh --ios --incremental
```
Build settings use `RUST_LIB_PLATFORM` to select device vs simulator library.
README_EOF
echo -e "${GREEN}Distributed to: $IOS_APP_DIST${NC}"
@@ -626,8 +667,11 @@ if $BUILD_DOTNET; then
fi
if $BUILD_IOS; then
IOS_BUILD_SKIPPED=false
build_ios
distribute_ios
if [ "$IOS_BUILD_SKIPPED" = false ]; then
distribute_ios
fi
fi
if $BUILD_ANDROID; then