Rust code that can be used to generate Kotlin and Swift bindings for wysiwyg-rust.
See the installation guide.
uniffi-bindgen
is used to generate the Kotlin and Swift bindings.
It's important that the version of uniffi-bindgen
that you install globally matches the version of uniffi
declared in this project.
Find the version of uniffi
in bindings/wysiwyg-ffi/Cargo.toml
and install uniffi-bindgen
using the following command:
cargo install uniffi_bindgen --version <uniffi-version>
Configure Rust for cross compilation to any target platforms you'll need.
# Android targets
rustup target add aarch64-linux-android # for most physical Android devices
rustup target add x86_64-linux-android # for Android emulator on PC
rustup target add i686-linux-android # for 32-bit Android emulators
rustup target add armv7-linux-androideabi # for older devices
# iOS targets
rustup target add aarch64-apple-ios
rustup target add aarch64-apple-ios-sim
rustup target add x86_64-apple-ios
Ensure you have first completed the steps to install and configure Rust.
The simplest way to do this is by installing Android Studio.
Find the required NDK version by searching for ndkVersion
in platforms/android/library/build.gradle
.
Now install the NDK, the simplest way being to use the Android SDK manager from within Android Studio.
Note: If you decide to install the NDK manually, you must still use the "side-by-side" structure (i.e. the NDK must be inside the Android SDK directory, in a path like ~/Android/Sdk/ndk/22.1.7171670
).
Note: at time of writing (2022-06-28) you needed to use android-ndk-r22b or
earlier, because later versions fail with an error like ld: error: unable to find library -lgcc
. See rust-lang #85806 for more.
Create a Cargo config at bindings/wysiwyg-ffi/.cargo/config.toml
to tell Cargo where to look for the NDK during cross compilation (more details in the Cargo reference).
Add any platforms that you need to target to this file, replacing instances of NDK_HOME
with the location of your NDK (for example/home/andy/Android/Sdk/ndk/22.1.7171670
).
# bindings/wysiwyg-ffi/.cargo/config.toml
[target.aarch64-linux-android]
ar = "NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/ar"
linker = "NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang"
[target.x86_64-linux-android]
ar = "NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/ar"
linker = "NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android30-clang"
Note: You may need to add additional targets, for example i686
if you use a 32-bit emulator.
Note: this file is ignored in the top-level .gitignore
file, so it won't be checked in to Git.
The following command builds the whole library and deploys it to Maven local for local development.
# Ensure ANDROID_HOME is set correctly!
make android
cd bindings/wysiwyg-ffi
cargo build --target x86_64-linux-android --release
This will create:
../../target/x86_64-linux-android/release/libuniffi_wysiwyg_composer.so
To strip the libraries and make them smaller:
NDK_HOME/toolchains/x86_64-4.9/prebuilt/linux-x86_64/bin/x86_64-linux-android-strip \
../../target/x86_64-linux-android/debug/libuniffi_wysiwyg_composer.so
Ensure you have first completed the steps to install and configure Rust.
- Build shared object:
cd bindings/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/libwysiwyg_ffi.a \
../../target/aarch64-apple-ios-sim/release/libwysiwyg_ffi.a \
-output ../../target/ios-simulator/libwysiwyg_ffi.a
- This will create static libraries for both iOS devices and simulators:
../../target/x86_64-apple-ios/debug/libwysiwyg_ffi.a
../../target/ios-simulator/libwysiwyg_ffi.a
- Generate the bindings inside given output dir:
Cargo.toml
content inside this directory to retrieve it and use
cargo install uniffi_bindgen --version <VERSION_NUMBER>
if needed.
uniffi-bindgen \
generate src/wysiwyg_composer.udl \
--language swift \
--config uniffi.toml \
--out-dir MY_OUTPUT_DIR
cd MY_OUTPUT_DIR
mv *.h headers/
mv *.modulemap headers/module.modulemap
mv *.swift Sources/
Note: The project should always have a single Swift modulemap file, and it
should be named module.modulemap
otherwise the generated framework will not
expose symbols properly to Swift.
- Generate the .xcframework file:
xcodebuild -create-xcframework \
-library ../../target/aarch64-apple-ios/debug/libwysiwyg_composer.a" \
-headers MY_OUTPUT_DIR/headers \
-library MY_OUTPUT_DIR/libwysiwyg_composer.a" \
-headers MY_OUTPUT_DIR/headers \
-output MY_OUTPUT_DIR/ExampleRustBindings.xcframework"
Now you can use the framework wherever you see fit, just add the framework (as
well as the generated Swift code from MY_OUTPUT_DIR/Sources/
) as a dependency
inside an existing XCode project, or package them with your preferred dependency
manager. See
Example Rust Bindings
for a full example of how it all fits together.