/android-rs-glue

Glue between Rust and Android

Primary LanguageRustApache License 2.0Apache-2.0

What is this repository?

This repository consists in two crates: a binary named apk-builder, and a library named android_glue.

apk-builder is a wrapper around gcc and the Android SDK and NDK. Invoking it will produce an .apk (Android package) instead of a regular binary.

This linker is supposed to be used alongside with android_glue, which is a low-level library that will allow you to access the Android environment (the window, the events, etc.). android_glue is supposed to be used as a dependency for higher-level libraries that require access to this environment, like gl-init.

Installation

You can make any program run on Android with the following steps.

First, add a dependency to android_glue:

[dependencies.android_glue]
git = "https://github.com/tomaka/android-rs-glue"

Then, add extern crate android_glue and invoke android_start! in your main crate.

#[cfg(target_os = "android")]
#[macro_use] 
extern crate android_glue;

#[cfg(target_os = "android")]
android_start!(main);

fn main() {
    // ...
}

Then, clone or download this repository somewhere on your computer and compile apk-builder.

git clone https://github.com/tomaka/android-rs-glue apk-builder
cd apk-builder/apk-builder
cargo build

Finally, add a file named .cargo/config in your main repository in order to ask rustc to use apk-builder:

[target.arm-linux-androideabi]
linker = "apk-builder/apk-builder/target/apk-builder"

Instead of a regular binary, compiling with cargo build --target=arm-linux-androideabi will produce an APK that can be installed on an Android device. See How to compile below.

One important thing to notice is that this doesn't break your existing build. Calling cargo build or cargo build --target=something-something-something will produce the exact same thing as before.

Usage

  • android_start!(main) defines the entry point of your application to main.

The library provides other unsafe low-level functions, but they should only be used by higher-level libraries that need access to the Android environment.

How to compile

Setting up your environment

  • If you are on Linux 64 bits, install the 32 bits binaries (apt-get install libc6-i386 lib32z1 lib32stdc++6)

  • Download and unzip the Android NDK

  • Generate a stand-alone toolchain of the NDK, example: ./android-ndk-r10/build/tools/make-standalone-toolchain.sh --platform=android-L --toolchain=arm-linux-androideabi --install-dir=/opt/ndk_standalone --ndk-dir=/home/you/android-ndk-r10

  • Clone the Rust compiler: git clone https://github.com/rust-lang/rust.git

  • Compile Rust for Android: mkdir rust-build, cd rust-build, ../rust/configure --target=arm-linux-androideabi --android-cross-path=/opt/ndk_standalone, make, make install

  • Download and unzip Cargo

  • Install Cargo: ./cargo-nightly-x86_64-unknown-linux-gnu/install.sh

  • Install the Java JDK and Ant (apt-get install openjdk-7-jdk ant)

  • Download and unzip the Android SDK (under SDK tools in VIEW ALL DOWNLOADS AND SIZES)

  • Update the SDK: ./android-sdk-linux/tools/android update sdk -u

Building your project

Building your project is done in one single step:

ANDROID_HOME=/path/to/android/sdk NDK_HOME=/path/to/ndk NDK_STANDALONE=/opt/ndk_standalone cargo build --target=arm-linux-androideabi

(Note: the SDK installer should automatically set ANDROID_HOME, in which case you don't need to pass it. The NDK standalone may be by-passed in the future, making NDK_HOME the only environment variable that will need to be passed).

This will generate a file named target/arm-linux-androideabi/your_crate or target/arm-linux-androideabi/your_crate.exe. Even though it has the wrong extension, this file is an Android package (.apk) that can be installed on an Android device.

Testing on an Android emulator

Start the emulator, then run:

adb install -r target/your_crate

This will install your application on the emulator.

For the moment, your application's name is always the name of your crate. This will be customizable in the future.