Home

Awesome

Steps

Rust

Build for iOS

iOS with CocoaPods

CocoaPods have a lot of requirements to push them to the repo, like having a valid LICENSE file, making a different branch for every version, and storing every podspec file in a github repository, so be prepared to spend some time fighting those issues.

Build for Android

Android plugin with Gradle

Loading the Android plugin

in settings.gradle:

include ':InRustWeTrust'
project(':InRustWeTrust').projectDir = new File('<PATH_TO>/rust_on_mobile/android')

in build.gradle:

dependencies {
    compile project(path: ':InRustWeTrust')
}

in gradle.properties: android.useDeprecatedNdk=true

in local.properties (update paths accordingly):

sdk.dir=/path/to/android-sdk-macosx
ndk.dir=/usr/local/Cellar/android-ndk/r11c

In the app's code, import com.geal.InRustWeTrust; and Log.d("TEST", "result: "+Integer.toString(InRustWeTrust.add(1, 2)));

Questions

Should the exported C symbols be in another crate depending on the main library?

Right now, the exported C symbols will also end up in the Android library

everything is done manually to write JNI functions right now, could it be automated a bit more?

Can we generate the Java classes? Can we avoid writing Java_com_etc? maybe with a compiler plugin

how can we generate a static library with apple's bitcode format?

The current way for iOS is to generate a so-called "universal binary" that will contain code for all targeted architectures. Apple decided that since binaries are becoming large (well, not that large compared to all the Retina aware icons, but I digress), they will make a library format containing LLVM bitcode that will be precompiled by Apple, so that you only receive the binaries for your arch when you download an app (cf http://lowlevelbits.org/bitcode-demystified/ for more info).

We can generate LLVM bitcode with Rust, but there's an incompatibility in the formats. Apple's clang uses the following version:

$ xcrun clang -v
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin14.5.0
Thread model: posix

From what I understand, Rust uses LLVM 3.8.1.

Apparently, The flag used to ship bitcode in the library is available from LLVM 3.8.1, but Apple used it in its 3.7 fork before contributing it back. So the bitcode generated by rustc could be incompatible:

$ cd inrustwetrust/
$ cargo rustc -- --emit llvm-ir
[...]
$ xcrun clang -c target/debug/inrustwetrust.ll
target/debug/inrustwetrust.ll:9:133: error: expected value token
  ...{ %str_slice, %str_slice, i32 } { %str_slice { i8* getelementptr inbounds ([30 x i8], [30 x i8]* @str6...
                                                                                         ^
1 error generated.

So it looks like right now, it's impossible to generate an iOS library from Rust using the bitcode format.

Exception unwinding is apparently incompatible between Rust and ObjectiveC because of compact unwinding

Linking the app can fail with the following error:

ld: too many personality routines for compact unwind to encode for architecture x86_64

This can be fixed by passing -Wl,-keep_dwarf_unwind -Wl,-no_compact_unwind as "other linker flags". From what I understand, Objective C has a different exception unwinding system that is not using the dwarf based one like Rust.

Another idea would be to remove exception unwinding from the rust code, with a panic=abort, but that means any exception would generate a crash in the Rust code, which is not a great solution.