Rightpoint / Rust Universal Template
Programming Languages
Projects that are alternatives of or similar to Rust Universal Template
Rust Universal Template
Template for creating universal Rust libraries with bindings to iOS/macOS (Swift), Android (Java/JNI), JavaScript (WebAssembly), and more.
Goals
- [ ] iOS / macOS
- [x] Swift Framework template
- [x] Run
cargo
via Xcode External Build System - [x] Carthage support
- [ ] CocoaPods support
- [ ] Automated Rust => Swift binding generation
- [x] Example iOS app
- [ ] Android / Java
- [ ] Gradle library template
- [ ] Automated Rust => Java/JNI binding generation
- [x] Pure Java example
- [ ] Example Android app
- [ ] Web Browsers / JavaScript
- [ ] JavaScript / WebAssembly template
- [ ] Automated Rust => JavaScript binding generation (wasm-bindgen)
- [ ] Example app
- [ ] General
- [ ] Automated Rust => C binding generation (cbindgen)
- [ ] Create cookiecutter template
- [ ] Documention and examples for best practices when using Rust from other languages
Setup
Install Rust via Rustup:
$ curl https://sh.rustup.rs -sSf | sh
Make sure the Rust binaries are added to your PATH
(e.g. inside ~/.profile
). This is usually performed automatically for you by rustup
.
export PATH="$HOME/.cargo/bin:$PATH"
iOS
Install the iOS targets for your selected toolchain:
$ rustup target add aarch64-apple-ios armv7-apple-ios x86_64-apple-ios i386-apple-ios
Install cargo-lipo
for generating universal iOS libraries:
$ cargo install cargo-lipo
Bitcode
If you want Bitcode support you'll need to use a Rust nightly 1.2.7+ build (as of 4-27-2018). Unfortunately there still seems to be some issues with Bitcode so it is disabled for now. For more information see issue https://github.com/rust-lang/rust/issues/35968.
$ rustup toolchain install nightly
$ rustup target add aarch64-apple-ios armv7-apple-ios x86_64-apple-ios i386-apple-ios --toolchain nightly
$ rustup default nightly
Android
Install Android NDK (tested on version r16b):
$ brew cask install android-ndk
Add ANDROID_NDK_HOME
to your bash profile (e.g. ~/.profile
):
export ANDROID_NDK_HOME="/usr/local/share/android-ndk"
Install Android Rust targets:
$ rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
Run build-android.sh
. This will create a standalone NDK toolchain and in the NDK
directory if needed, and then run cargo build
for all Android targets.
$ ./build-android.sh
Java
To regenerate the Java JNI bindings, you need to first compile the Java with javac
and then run javah
to generate a C header. This generated header HelloWorld.h
shows us the expected method signature for the JNI function.
# Compile Java
$ javac Source/Java/HelloWorld.java
# Generate C header JNI interface
$ javah -classpath Source/Java -d Source/Java HelloWorld
The corresponding Rust source code can be found in Source/Rust/java/src/lib.rs
. We must first compile it, so the output shared library (libexample.dylib
on macOS) can be found by Java.
$ cargo build --features "java" --release
Finally, we can run our Java code that calls into the Rust code:
$ javac Examples/Java/HelloWorld/Main.java -classpath Source/Java
$ java -Djava.library.path=target/release -classpath "Source/Java:Examples/Java/HelloWorld" Main
Hello, from Rust!!
Install Visual Studio Code (optional)
VS Code offers an IDE-like experiene for developing your Rust code, including some rough LLDB debugging support.
-
VS Code
- rls-vscode (code completion)
- vscode-lldb (debugging)
Structure
Source/Rust
The src folder contains all of our Rust library source code (.rs
) and a manually created C header file (example.h
) exporting a few symbols of interest from our Rust code. The build output is a static library called libexample.a
.
ExampleObjC.framework
This iOS/macOS framework contains a Objective-C wrapper around the the C interface exposed by example.h
.
ExampleSwift.framework
This iOS/macOS framework contains a Swift wrapper around the the C interface exposed by example.h
.
Reference
Tools
-
android-rs-glue - Glue between Rust and Android, including
cargo-apk
command - cargo-lipo - Cargo subcommand to automatically create universal libraries for iOS.
- cbindgen - A project for generating C bindings from Rust code
- wasm-bindgen - Interoperating JavaScript and Rust
- rust-bindgen - Automatically generates Rust FFI bindings to C (and some C++) libraries
Examples
- parity-signer - Rust + React Native (iOS & Android)
- cross-platform-rust - Example project showing a Rust library running on iOS and Android
- rust-to-ios - Example project for building a library for iOS in Rust.
- rust-ios-android - Example project for building Rust library for iOS and Android
- rust_on_mobile - iOS and Android examples
Articles
- JavaScript to Rust and Back Again: A wasm-bindgen Tale
- Building and Deploying a Rust library on Android
- Building and Deploying a Rust library on iOS
- Building for Android - Servo's Android toolchain setup
- Taking Rust everywhere with rustup
License
MIT