Skip to content
This repository has been archived by the owner on Sep 27, 2024. It is now read-only.

Revamp xcframework generation to avoid conflicts with other Rust libraries #742

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Generated
/target/
/bindings/wysiwyg-ffi/.cargo/
/bindings/wysiwyg-ffi/.generated/
/.generated/
/bindings/wysiwyg-wasm/pkg/
/bindings/wysiwyg-wasm/node_modules/
/platforms/android/example/.idea/
Expand Down
22 changes: 11 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 1 addition & 32 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,38 +26,7 @@ IOS_PACKAGE_DIR := ../../platforms/ios/lib/WysiwygComposer
IOS_GENERATION_DIR := .generated/ios

ios: setup
cd bindings/wysiwyg-ffi && \
cargo build --release --target aarch64-apple-ios && \
cargo build --release --target aarch64-apple-ios-sim && \
cargo build --release --target x86_64-apple-ios && \
mkdir -p ../../target/ios-simulator && \
lipo -create \
../../target/x86_64-apple-ios/release/libuniffi_wysiwyg_composer.a \
../../target/aarch64-apple-ios-sim/release/libuniffi_wysiwyg_composer.a \
-output ../../target/ios-simulator/libuniffi_wysiwyg_composer.a && \
rm -rf ${IOS_PACKAGE_DIR}/WysiwygComposerFFI.xcframework && \
rm -f ${IOS_PACKAGE_DIR}/Sources/WysiwygComposer/WysiwygComposer.swift && \
rm -rf ${IOS_GENERATION_DIR} && \
mkdir -p ${IOS_GENERATION_DIR} && \
uniffi-bindgen \
generate src/wysiwyg_composer.udl \
--language swift \
--config uniffi.toml \
--out-dir ${IOS_GENERATION_DIR} && \
mkdir -p ${IOS_GENERATION_DIR}/headers && \
mv ${IOS_GENERATION_DIR}/*.h ${IOS_GENERATION_DIR}/headers/ && \
mv ${IOS_GENERATION_DIR}/*.modulemap ${IOS_GENERATION_DIR}/headers/module.modulemap && \
mv ${IOS_GENERATION_DIR}/*.swift ${IOS_PACKAGE_DIR}/Sources/WysiwygComposer/ && \
xcodebuild -create-xcframework \
-library ../../target/aarch64-apple-ios/release/libuniffi_wysiwyg_composer.a \
-headers ${IOS_GENERATION_DIR}/headers \
-library ../../target/ios-simulator/libuniffi_wysiwyg_composer.a \
-headers ${IOS_GENERATION_DIR}/headers \
-output ${IOS_PACKAGE_DIR}/WysiwygComposerFFI.xcframework && \
sed -i "" -e '1h;2,$$H;$$!d;g' -e 's/) -> ComposerUpdate {\n return try! FfiConverterTypeComposerUpdate.lift(\n try!/) throws -> ComposerUpdate {\n return try FfiConverterTypeComposerUpdate.lift(\n try/g' ${IOS_PACKAGE_DIR}/Sources/WysiwygComposer/WysiwygComposer.swift && \
sed -i "" -e '1h;2,$$H;$$!d;g' -e 's/) -> ComposerUpdate/) throws -> ComposerUpdate/g' ${IOS_PACKAGE_DIR}/Sources/WysiwygComposer/WysiwygComposer.swift
# Note: we use sed to tweak the generated Swift bindings and catch Rust panics,
# this should be removed when the Rust code is 100% safe (see `ComposerModelWrapper.swift`).
@sh build_xcframework.sh

web: setup
cd bindings/wysiwyg-wasm && \
Expand Down
2 changes: 1 addition & 1 deletion bindings/wysiwyg-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ repository = "https://gitlab.com/andybalaam/wysiwyg-rust"
description = "Swift and Kotlin bindings for wysiwyg-rust"
keywords = ["matrix", "chat", "messaging", "composer", "wysiwyg"]
license = "Apache-2.0"
name = "uniffi-wysiwyg-composer"
name = "wysiwyg-ffi"
version = "2.3.1"
rust-version = "1.65"

Expand Down
77 changes: 77 additions & 0 deletions build_xcframework.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/usr/bin/env bash

GENERATION_PATH=.generated/ios

UDL_FILE_PATH=bindings/wysiwyg-ffi/src/wysiwyg_composer.udl
UNIFFI_CONFIG_FILE_PATH=bindings/wysiwyg-ffi/uniffi.toml

ARM64_LIB_PATH=target/aarch64-apple-ios/release/libwysiwyg_ffi.a
ARM64_SIM_LIB_PATH=target/aarch64-apple-ios-sim/release/libwysiwyg_ffi.a
X86_LIB_PATH=target/x86_64-apple-ios/release/libwysiwyg_ffi.a
SIM_LIB_PATH=target/ios-simulator/libwysiwyg_ffi.a

IOS_PATH=platforms/ios
TOOLS_PATH="${IOS_PATH}/tools"

SWIFT_PACKAGE_PATH="${IOS_PATH}/lib/WysiwygComposer"
SWIFT_BINDINGS_FILE_PATH="${SWIFT_PACKAGE_PATH}/Sources/WysiwygComposer/WysiwygComposer.swift"

XCFRAMEWORK_PATH="${SWIFT_PACKAGE_PATH}/WysiwygComposerFFI.xcframework"
XCFRAMEWORK_SIM_PATH="${XCFRAMEWORK_PATH}/ios-arm64_x86_64-simulator/WysiwygComposerFFI.framework"
XCFRAMEWORK_SIM_HEADERS_PATH="${XCFRAMEWORK_SIM_PATH}/Headers"
XCFRAMEWORK_SIM_MODULES_PATH="${XCFRAMEWORK_SIM_PATH}/Modules"
XCFRAMEWORK_SIM_LIBRARY_PATH="${XCFRAMEWORK_SIM_PATH}/WysiwygComposerFFI"
XCFRAMEWORK_ARM64_PATH="${XCFRAMEWORK_PATH}/ios-arm64/WysiwygComposerFFI.framework"
XCFRAMEWORK_ARM64_HEADERS_PATH="${XCFRAMEWORK_ARM64_PATH}/Headers"
XCFRAMEWORK_ARM64_MODULES_PATH="${XCFRAMEWORK_ARM64_PATH}/Modules"
XCFRAMEWORK_ARM64_LIBRARY_PATH="${XCFRAMEWORK_ARM64_PATH}/WysiwygComposerFFI"

# Build libraries for each platform
cargo build -p wysiwyg-ffi --release --target aarch64-apple-ios
cargo build -p wysiwyg-ffi --release --target aarch64-apple-ios-sim
cargo build -p wysiwyg-ffi --release --target x86_64-apple-ios

# Merge x86 and simulator arm libraries with lipo
mkdir -p target/ios-simulator
lipo -create $X86_LIB_PATH $ARM64_SIM_LIB_PATH -output $SIM_LIB_PATH

# Remove previous artefacts and files
rm -rf $XCFRAMEWORK_PATH
rm -f $SWIFT_BINDINGS_FILE_PATH
rm -rf $GENERATION_PATH

# Generate headers & Swift bindings
mkdir -p $GENERATION_PATH
uniffi-bindgen generate $UDL_FILE_PATH -l swift --config $UNIFFI_CONFIG_FILE_PATH --out-dir $GENERATION_PATH

# Move Swift file to expected location
#
# Note: we use sed to tweak the generated Swift bindings and catch Rust panics,
# this should be removed when the Rust code is 100% safe (see `ComposerModelWrapper.swift`).
mv "${GENERATION_PATH}/WysiwygComposer.swift" $SWIFT_BINDINGS_FILE_PATH
sed -i "" -e '1h;2,$H;$!d;g' -e 's/) -> ComposerUpdate {\n return try! FfiConverterTypeComposerUpdate.lift(\n try!/) throws -> ComposerUpdate {\n return try FfiConverterTypeComposerUpdate.lift(\n try/g' $SWIFT_BINDINGS_FILE_PATH
sed -i "" -e '1h;2,$H;$!d;g' -e 's/) -> ComposerUpdate/) throws -> ComposerUpdate/g' $SWIFT_BINDINGS_FILE_PATH

# Create xcframework hierarchy
mkdir -p $XCFRAMEWORK_SIM_HEADERS_PATH
mkdir $XCFRAMEWORK_SIM_MODULES_PATH
mkdir -p $XCFRAMEWORK_ARM64_HEADERS_PATH
mkdir $XCFRAMEWORK_ARM64_MODULES_PATH

# Copy/move files to expected locations
#
# Note: this and the hierarchy created above are actually
# replacing the call to xcodebuild's create-xcframework because
# it doesn't build up the hierarchy in a way that would avoid
# conflicts between multiple Rust libraries imported into the same
# hosting application. This does, because .framework objects
# have their own directory in DerivedData, whereas root headers
# directory module.modulemap files tend to conflict with each other
# as Xcode blindly moves them all to the same include folder.
mv $ARM64_LIB_PATH $XCFRAMEWORK_ARM64_LIBRARY_PATH
mv $SIM_LIB_PATH $XCFRAMEWORK_SIM_LIBRARY_PATH
cp ${GENERATION_PATH}/*.h $XCFRAMEWORK_SIM_HEADERS_PATH
mv ${GENERATION_PATH}/*.h $XCFRAMEWORK_ARM64_HEADERS_PATH
cp "${TOOLS_PATH}/Info.plist" $XCFRAMEWORK_PATH
cp "${TOOLS_PATH}/module.modulemap" $XCFRAMEWORK_SIM_MODULES_PATH
cp "${TOOLS_PATH}/module.modulemap" $XCFRAMEWORK_ARM64_MODULES_PATH
2 changes: 1 addition & 1 deletion platforms/android/library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ apply plugin: "com.vanniktech.maven.publish"

cargo {
module = "../../../crates" // Or whatever directory contains your Cargo.toml
libname = "uniffi-wysiwyg-composer" // Or whatever matches Cargo.toml's [package] name.
libname = "wysiwyg-ffi" // Or whatever matches Cargo.toml's [package] name.
targets = ["arm", "x86", "x86_64", "arm64"]
targetIncludes = ["libuniffi_wysiwyg_composer.so"]
targetDirectory = '../../../target'
Expand Down
40 changes: 40 additions & 0 deletions platforms/ios/tools/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>WysiwygComposerFFI.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>WysiwygComposerFFI.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>
4 changes: 4 additions & 0 deletions platforms/ios/tools/module.modulemap
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
framework module WysiwygComposerFFI {
umbrella header "WysiwygComposerFFI.h"
export *
}
Loading