Skip to content

Template for creating Rust libraries with bindings to iOS, Android, WebAssembly and more

License

Notifications You must be signed in to change notification settings

Rightpoint/rust-universal-template

Repository files navigation

Rust Universal Template

Swift 4.1 Rustc Version 1.25+ CircleCI Carthage compatible

Template for creating universal Rust libraries with bindings to iOS/macOS (Swift), Android (Java/JNI), JavaScript (WebAssembly), and more.

Goals

  • iOS / macOS
    • Swift Framework template
    • Run cargo via Xcode External Build System
    • Carthage support
    • CocoaPods support
    • Automated Rust => Swift binding generation
    • Example iOS app
  • Android / Java
    • Gradle library template
    • Automated Rust => Java/JNI binding generation
    • 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 rust-lang/rust#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.

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

Articles

License

MIT

About

Template for creating Rust libraries with bindings to iOS, Android, WebAssembly and more

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published