diff --git a/swift/apple/Makefile b/swift/apple/Makefile index fbf78cac5..502ed11bd 100644 --- a/swift/apple/Makefile +++ b/swift/apple/Makefile @@ -4,8 +4,14 @@ PLATFORM?=macOS ARCH=$(shell uname -m) CONFIGURATION?=Debug -# Path to rust target directory (relative to this Makefile) -RUST_TARGET_DIR=$(abspath ../../rust/target) +# Paths +RUST_DIR=$(abspath ../../rust) +RUST_TARGET_DIR=$(RUST_DIR)/target +CLIENT_FFI_DIR=$(RUST_DIR)/client-ffi +GENERATED_DIR=$(abspath FirezoneNetworkExtension/Connlib/Generated) + +# Find all Rust source files in client-ffi +CLIENT_FFI_SOURCES=$(shell find $(CLIENT_FFI_DIR)/src -name "*.rs" 2>/dev/null) # Set consistent environment to prevent Rust rebuilds # This must match the Xcode project setting @@ -23,16 +29,38 @@ GIT_SHA=$(shell git rev-parse HEAD 2>/dev/null || echo "unknown") # Default target: build and install .PHONY: all -all: build install +all: uniffi-bindings build install + +# Generate UniFFI bindings from Rust source +# This works on any platform (not just macOS) +$(GENERATED_DIR)/connlib.swift $(GENERATED_DIR)/connlibFFI.h: $(CLIENT_FFI_SOURCES) $(CLIENT_FFI_DIR)/Cargo.toml + @echo "Generating UniFFI bindings..." + @mkdir -p $(GENERATED_DIR) + @cd $(RUST_DIR) && \ + (test -f $(RUST_TARGET_DIR)/debug/libconnlib.a || cargo build -p client-ffi) && \ + cargo run -p uniffi-bindgen -- generate \ + --library $(RUST_TARGET_DIR)/debug/libconnlib.a \ + --language swift \ + --out-dir $(GENERATED_DIR) + @rm -f $(GENERATED_DIR)/*.modulemap + @if [ -f "$(GENERATED_DIR)/connlib.swift" ]; then \ + sed -i.bak '/#if canImport(connlibFFI)/,/#endif/s/^/\/\/ /' $(GENERATED_DIR)/connlib.swift; \ + rm -f $(GENERATED_DIR)/connlib.swift.bak; \ + fi + @echo "✅ UniFFI bindings generated" + +.PHONY: uniffi-bindings +uniffi-bindings: $(GENERATED_DIR)/connlib.swift $(GENERATED_DIR)/connlibFFI.h # Info for sourcekit-lsp (LSP server for other IDEs) +.PHONY: lsp lsp: @xcode-build-server config \ -project Firezone.xcodeproj \ -scheme Firezone .PHONY: build -build: +build: $(GENERATED_DIR)/connlib.swift $(GENERATED_DIR)/connlibFFI.h @echo "Building Xcode project for ${PLATFORM}, ${ARCH}" @echo "Git SHA: ${GIT_SHA}" @xcodebuild build \ @@ -70,7 +98,7 @@ clean: -sdk macosx @echo "Cleaning Rust build artifacts" @cd ../../rust/client-ffi && cargo clean - @echo "Removing Generated bindings" + @echo "Removing generated bindings" @rm -rf FirezoneNetworkExtension/Connlib/Generated .PHONY: format diff --git a/swift/apple/build-rust.sh b/swift/apple/build-rust.sh index 77bd85778..dcfdecb9d 100755 --- a/swift/apple/build-rust.sh +++ b/swift/apple/build-rust.sh @@ -7,7 +7,6 @@ trap 'echo "ERROR: Build script failed at line $LINENO" >&2' ERR # Get script directory SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" RUST_DIR="$SCRIPT_DIR/../../rust" -GENERATED_DIR="$SCRIPT_DIR/FirezoneNetworkExtension/Connlib/Generated" # Sanitize the environment to prevent Xcode's shenanigans from leaking # into our highly evolved Rust-based build system. @@ -136,9 +135,9 @@ for target in "${TARGETS[@]}"; do fi done -# Step 1: Build Rust library +# Build Rust library echo "" -echo "Step 1/3: Building Rust library..." +echo "Building Rust library..." # Build target list for cargo command target_list="" @@ -158,47 +157,14 @@ for target in "${TARGETS[@]}"; do fi done -# Step 2: Generate UniFFI bindings +# Generate UniFFI bindings echo "" -echo "Step 2/3: Generating UniFFI bindings..." -mkdir -p "$GENERATED_DIR" - -# Use the first target's library for generating bindings (they're the same for all architectures) -FIRST_TARGET="${TARGETS[0]}" -LIBRARY_PATH="$CARGO_TARGET_DIR/$FIRST_TARGET/$BUILD_DIR" - -cargo run -p uniffi-bindgen -- generate \ - --library "$LIBRARY_PATH/libconnlib.a" \ - --language swift \ - --out-dir "$GENERATED_DIR" - -# Remove module maps (we use bridging header instead) -rm -f "$GENERATED_DIR"/*.modulemap - -# Fix imports in generated Swift file to use bridging header -if [ -f "$GENERATED_DIR/connlib.swift" ]; then - # Comment out the #if canImport(connlibFFI) block - sed -i.bak '/#if canImport(connlibFFI)/,/#endif/s/^/\/\/ /' "$GENERATED_DIR/connlib.swift" - rm -f "$GENERATED_DIR/connlib.swift.bak" -fi - -# Step 3: Verify generated files -echo "" -echo "Step 3/3: Verifying generated files..." -if [ ! -f "$GENERATED_DIR/connlib.swift" ]; then - echo "ERROR: Generated Swift file not found" >&2 - exit 1 -fi - -if [ ! -f "$GENERATED_DIR/connlibFFI.h" ]; then - echo "ERROR: Generated header file not found" >&2 - exit 1 -fi +echo "Generating UniFFI bindings..." +cd "$SCRIPT_DIR" +make uniffi-bindings echo "" -echo "✅ Build completed successfully!" -echo " Swift bindings: $GENERATED_DIR/connlib.swift" -echo " C header: $GENERATED_DIR/connlibFFI.h" +echo "✅ Rust library build completed successfully!" echo " Built libraries:" for target in "${TARGETS[@]}"; do echo " - $CARGO_TARGET_DIR/$target/$BUILD_DIR/libconnlib.a"