• Stars
    star
    167
  • Rank 219,550 (Top 5 %)
  • Language
    Objective-C
  • Created almost 8 years ago
  • Updated almost 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Steps

Rust

  • Create the Rust library
  • export some symbols with libc (for iOS)
  • use rusty-cheddar to generate the headers, or write them manually

Build for iOS

  • install cargo-lipo: cargo install cargo-lipo
  • install the required toolchains:
    • rustup target add aarch64-apple-ios
    • rustup target add armv7-apple-ios
    • rustup target add armv7s-apple-ios
    • rustup target add i386-apple-ios
    • rustup target add x86_64-apple-ios

iOS with CocoaPods

  • install the cocoapods: sudo gem install cocoapods (cf https://cocoapods.org/ )
  • use the command pod lib create InRustWeTrustKit to create the pod with an example app
  • remove the .git folder in the pod
  • move the podspec file at the root of the project
  • change InRustWeTrustKit/Example/Podfile to point to the pod at ../../ instead of ../
  • update the source_files path in the podspec from InRustWeTrustKit/Classes/**/* to InRustWeTrustKit/InRustWeTrustKit/Classes/**/*
  • add the prepare_command in the podspec file to build the library
  • use pod lib lint --verbose to verify the podspec file
  • cd InRustWeTrustKit/Example && pod install --verbose to test building with the example app

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

  • download the Android NDK
  • Create the rust-jni project to host the JNI interface: cargo new rust-jni. It will generate a dylib
  • add the original project as dependency by path
  • create the JNI export functions
  • write a .cargo/config file with the following content (adjust the paths, platform and SDK version accordingly):
    [target.arm-linux-androideabi]
    ar = "/usr/local/Cellar/android-ndk/r11c/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-ar"
    linker = "/Users/geal/dev/rust_on_mobile/rust-jni/linker-wrapper.sh"
    
  • the rust-jni/linker-wrapper.sh file was a ugly hack I needed to link when a link option was unavailable with the linker version, not sure it's still needed
  • cargo build --target=arm-linux-androideabi
  • cp target/arm-linux-androideabi/debug/libinrustwetrust.so ../android/src/main/jniLibs/armeabi/libinrustwetrust.so
  • cp target/arm-linux-androideabi/debug/libinrustwetrust.so ../android/src/main/jniLibs/armeabi-v7a/libinrustwetrust.so (we should probably build with another arch there)

Android plugin with Gradle

  • create an Android library project with Android studio, put it in the android/ directory
  • create the classes corresponding to the exported interface
  • load the library. The dylibs should be in src/main/jniLibs/<arch>/

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.

More Repositories

1

serverless-wasm

Rust
172
star
2

rust-syslog

Send syslog messages from Rust
Rust
97
star
3

lovecraft

You've met with a terrible fate, haven't you?
Rust
59
star
4

PilotSSH-scripts

A collection of scripts usable with the PilotSSH iOS app
Shell
54
star
5

tracing_allocator

This custom Rust allocator logs all memory actions for further analysis
Rust
51
star
6

pgo-rust

Testing LLVM's profile guided optimization with Rust
Assembly
45
star
7

cargo-external-doc

integrate markdown files with your rustdoc generated documentation
Rust
36
star
8

sbt-clojure

SBT plugin building Clojure code
Scala
31
star
9

mutguard

Run a function after some data was mutably borrowed
Rust
30
star
10

grad

aggregate, store, query and visualize your metrics, all in one tool
Rust
28
star
11

pod

POD the PHP preprocessor
PHP
25
star
12

nomfun

experimental new design for nom parser combinators
Rust
21
star
13

android-wireguard

Java
17
star
14

rust-vlc-demux

C
15
star
15

crates_you_should_do

list of Rust crates ideas you could take as first project
15
star
16

vlc_module.rs

Helper library to write VLC modules in Rust
Rust
14
star
17

proust

single node kafka implementation
Rust
14
star
18

gif.rs

Rust
13
star
19

mutant

Mutation testing for Rust
Rust
13
star
20

rust-ebpf-demo

Rust
11
star
21

Unpapered

An unhosted Instapaper clone
JavaScript
10
star
22

rust-csv

A CSV parser for Rust
Rust
10
star
23

sbt-clojure-example

Example code for https://github.com/Geal/sbt-clojure
Scala
9
star
24

rust-wasm-canvas

JavaScript
8
star
25

typedopts

Type aware command line parser in Rust
Rust
8
star
26

pestvsnom

C
7
star
27

generic-http-client

a Rust HTTP client that uses whatever transport you give it
Rust
7
star
28

langsec-2017-hackathon-code

Rust
7
star
29

rustfix

Automated fixes to follow Rust's recent developments
Python
7
star
30

cargo-plugin

compile time plugins for your Rust projects
Rust
7
star
31

Squeak-VM

A Git repository of the Squeak virtual machine, not synchronized with SVN repository anymore. For up to date code, see https://github.com/OpenSmalltalk/opensmalltalk-vm
C
6
star
32

dataexponential

a naive datalog implementation that probably does not run in logarithmic time
Rust
6
star
33

cargo-real-deps

Cargo subcommand to check which crates are built depending on features
Rust
5
star
34

the-regexperiment

making a safe cross language regular expression library
4
star
35

langsec-2017-Writing-Parsers-Like-it-is-2017

JavaScript
4
star
36

DevoxxFR-2022-University-Comprendre_GraphQL

JavaScript
4
star
37

nom-specialized

more advanced versions of some nom combinators
Rust
4
star
38

rust-plugin-test

nothing to see here (yet)
Rust
3
star
39

rust-devoxx2016

Java
3
star
40

archlinux-pharo-image

Docker image for Pharo Smalltalk
Shell
3
star
41

Curator

A PHP library designed to help you validate user input
PHP
3
star
42

wai.rs

experiment reproducing the Haskell WAI in Rust
Rust
3
star
43

trailer

Store a type with an associated buffer in contiguous memory
Rust
3
star
44

Head-Hunter-Hunter

Ruby
2
star
45

hakyll-search-prototype

An example hakyll used to hack a bit
JavaScript
2
star
46

rate_limit

Ruby
2
star
47

Journal.js

a small and versatile logging framework
JavaScript
2
star
48

bittorrent

Rust implementation of the BitTorrent Protocol: http://www.bittorrent.org/beps/bep_0003.html
Rust
2
star
49

generic-http-server

Rust
2
star
50

async-alloc-counter

count allocations in Rust futures
Rust
2
star
51

pharsec

A parser combinator library for PHP
PHP
2
star
52

nom_in_c

Experiments around calling nom parsers from C code
M4
2
star
53

Pyssenlit

A Python IDE storing the source code in database, inspired by Omnibrowser and Monticello
Python
2
star
54

archlinux-rust

Shell
2
star
55

Chef-Presentation

Slides for Riviera.rb presentation (April 2012)
JavaScript
1
star
56

Privacy-preserving-social-buttons

JavaScript
1
star
57

Sandpit

A sandboxing application for Windows
C
1
star
58

nom_colored_hexdump

Rust
1
star
59

build-metadata

embed repository metadata in your code at compile time
Rust
1
star
60

Worst-Case-Messaging-Protocol

C++
1
star
61

todo-cpp

C++
1
star
62

MockCA

A simple web application designed to create and revoke certificate authorities and certificate.
Ruby
1
star
63

biscuit-node-express

express middleware for Biscuit tokens
JavaScript
1
star
64

bencoders

A simple rust library for parsing bencode, written using nom.
Rust
1
star
65

pharo-seaside-docker-example

Smalltalk
1
star
66

pilotssh.com

Pilotssh.com website
JavaScript
1
star
67

fn_box

box up yo FnOnces
Rust
1
star
68

cpp-course

1
star
69

macro-parser

Rust
1
star
70

varargs

Rust
1
star
71

hv

Rust
1
star