Building a mobile app in Rust and React Native, Part 1: Project Setup

Marek Kotewicz
Aug 2, 2017 · 3 min read

The first post in series ‘building a mobile app in Rust and React Native’.

In this series I will describe process of connecting mobile front-end written in React Native with business logic written in Rust.

As an introduction to this article, I suggest reading a great series from John Gallagher: Building an iOS App in Rust, Part 1: Getting Started with Rust

The app we are building is a mobile wallet for ethereum cryptocurrency. It is able create brainwallet accounts, scan qr-codes with unsigned transactions and sign them.

Image for post
Image for post

The main reason why I decided to use Rust in this project was that I already had all modules written in it and ready to use (or at least I thought so).

Required tools

Setting up cross compilation

Once all dependencies are installed, lets set them up. We will start with installing all necessary toolchains.

# ios
rustup target add i386-apple-ios
rustup target add x86_64-apple-ios
rustup target add armv7-apple-ios
rustup target add armv7s-apple-ios
rustup target add aarch64-apple-ios
# android
rustup target add aarch64-linux-android
rustup target add armv7-linux-androideabi
rustup target add i686-linux-android

Now, let’s create a new project.

react-native init our_project

Next, create rust subdirectory, enter it and run

cargo new our_project

After those steps, the project directory should look like this:

__test__
android
app.json
index.android.js
index.ios.js
ios
node_modules
package.json
rust
/our_project
/Cargo.toml
/src

Next, let’s setup makefile the project and place it inside our_project dir.

ARCHS_IOS = i386-apple-ios x86_64-apple-ios armv7-apple-ios armv7s-apple-ios aarch64-apple-ios
ARCHS_ANDROID = aarch64-linux-android armv7-linux-androideabi i686-linux-android
LIB=libsigner.a
all: ios androidios: $(LIB)android: $(ARCHS_ANDROID)
sh copy_android.sh
.PHONY: $(ARCHS_IOS)
$(ARCHS_IOS): %:
cargo build --target $@ --release
.PHONY: $(ARCHS_ANDROID)
$(ARCHS_ANDROID): %:
cargo build --target $@ --release
$(LIB): $(ARCHS_IOS)
lipo -create -output $@ $(foreach arch,$(ARCHS_IOS),$(wildcard target/$(arch)/release/$(LIB)))

copy_android.sh is a shell script that copies our statically compiled libraries to jniLibs directory.

#! /bin/bashmkdir -p ../../android/app/src/main/jniLibs
mkdir -p ../../android/app/src/main/jniLibs/x86
mkdir -p ../../android/app/src/main/jniLibs/arm64-v8a
mkdir -p ../../android/app/src/main/jniLibs/armeabi-v7a
cp ./target/i686-linux-android/release/libsigner.so ../../android/app/src/main/jniLibs/x86/libsigner.so
cp ./target/aarch64-linux-android/release/libsigner.so ../../android/app/src/main/jniLibs/arm64-v8a/libsigner.so
cp ./target/armv7-linux-androideabi/release/libsigner.so ../../android/app/src/main/jniLibs/armeabi-v7a/libsigner.so

At this point we can already compile static libraries for android and iOS.

*disclosure

If your rust code links C libraries, the compilation will fail. To make it work, we need to set up custom linker. It can be done inside rust/.cargo/config file. You can use create-ndk-standalone.sh to generate it.

[target.aarch64-linux-android]
ar = "/Users/marek/projects/ethcore/native-signer/NDK/arm64/bin/aarch64-linux-android-ar"
linker = "/Users/marek/projects/ethcore/native-signer/NDK/arm64/bin/aarch64-linux-android-gcc"
[target.armv7-linux-androideabi]
ar = "/Users/marek/projects/ethcore/native-signer/NDK/arm/bin/arm-linux-androideabi-ar"
linker = "/Users/marek/projects/ethcore/native-signer/NDK/arm/bin/arm-linux-androideabi-gcc"
[target.i686-linux-android]
ar = "/Users/marek/projects/ethcore/native-signer/NDK/x86/bin/i686-linux-android-ar"
linker = "/Users/marek/projects/ethcore/native-signer/NDK/x86/bin/i686-linux-android-gcc"

At this point our project directory should look like like this:

__test__
android
app.json
index.android.js
index.ios.js
ios
node_modules
package.json
rust
/.cargo
/
config
/our_project
/
Cargo.toml
/copy_android.sh
/Makefile
/src

In next blog post I will cover making calls between Rust and React Native.

Project’s github repo.

follow me on twitter

follow me on github

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store