chore(apple): allow generating UniFFI bindings on Linux (#10600)

To generate the UniFFI bindings, we don't actually need to be on an
Apple device. To make cross-platform development a bit easier, we
extract the binding generation step into the Makefile.
This commit is contained in:
Thomas Eizinger
2025-10-17 12:49:33 +11:00
committed by GitHub
parent 8a6f60a2ec
commit b70865564d
2 changed files with 40 additions and 46 deletions

View File

@@ -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

View File

@@ -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"