How to Cross-Compile librav1e for Android and iOS

This guide provides a clear, step-by-step walkthrough for cross-compiling librav1e—the C-compatible library interface of the rav1e AV1 encoder—for Android and iOS devices. You will learn how to set up your environment, install the correct Rust target toolchains, and use cargo-c to build the static libraries (.a) and header files required for mobile application integration.

Step 1: Install Prerequisites

Before compiling, you need the Rust toolchain and cargo-c, a helper utility that simplifies building and installing C-compatible libraries from Rust crates.

  1. Install Rust via rustup if you have not already:

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  2. Install the cargo-c executable:

    cargo install cargo-c
  3. Clone the rav1e repository and navigate to its directory:

    git clone https://github.com/xiph/rav1e.git
    cd rav1e

Step 2: Cross-Compiling for Android

To compile for Android, you must have the Android NDK installed and configured.

1. Add Android Rust Targets

Install the target architectures you wish to support:

rustup target add aarch64-linux-android \
                  armv7-linux-androideabi \
                  i686-linux-android \
                  x86_64-linux-android

2. Configure the NDK Toolchain Environment

You must point Rust to your Android NDK compilers. The easiest way to manage this is by installing cargo-ndk:

cargo install cargo-ndk

Set the ANDROID_NDK_HOME environment variable to your NDK path:

export ANDROID_NDK_HOME=/path/to/your/Android/Sdk/ndk/25.x.xxxxxxx

3. Build the Library

Run cargo ndk combined with cargo cbuild to generate the libraries. For example, to build for 64-bit ARM (modern Android devices):

cargo ndk -t aarch64-linux-android cargo cbuild --release

The compiled static library (librav1e.a), shared library (librav1e.so), and C header files will be generated inside the target/aarch64-linux-android/release/ directory.


Step 3: Cross-Compiling for iOS

Compiling for iOS requires macOS with Xcode and the command-line tools installed.

1. Add iOS Rust Targets

Add the targets for physical devices (ARM64) and simulator environments:

rustup target add aarch64-apple-ios \
                  x86_64-apple-ios \
                  aarch64-apple-ios-sim

2. Build the Library for iOS Devices

To build the static library for physical iOS devices (64-bit ARM):

cargo cbuild --target aarch64-apple-ios --release

The output will be located in target/aarch64-apple-ios/release/.

3. Build the Library for the iOS Simulator

To build for the Simulator on Intel-based Macs:

cargo cbuild --target x86_64-apple-ios --release

To build for the Simulator on Apple Silicon (M1/M2/M3) Macs:

cargo cbuild --target aarch64-apple-ios-sim --release

4. Create a Universal (Fat) Library (Optional)

If you want to package both the device and simulator binaries into a single library for easier Xcode integration, use the lipo tool:

lipo -create \
  target/aarch64-apple-ios/release/librav1e.a \
  target/aarch64-apple-ios-sim/release/librav1e.a \
  -output target/librav1e-universal.a

The resulting librav1e-universal.a file, alongside the generated C headers in target/<target-name>/release/, can now be imported directly into your iOS or Android projects.