blob: 0de3e46cafe84de626ee54b7b1142b7ab02d0bed [file] [log] [blame] [view]
# Getting Started on Android with CMake
<!--
Notes to those updating this guide:
* This document should be __simple__ and cover essential items only.
Notes for optional components should go in separate files.
-->
This guide walks through cross-compiling IREE core runtime towards the Android
platform. Cross-compiling IREE compilers towards Android is not supported at the
moment.
Cross-compilation involves both a *host* platform and a *target* platform. One
invokes compiler toolchains on the host platform to generate libraries and
executables that can be run on the target platform.
## Prerequisites
### Set up host development environment
The host platform should have been set up for developing IREE. Right now only
Linux is supported; Windows and macOS support is coming. Please make sure you
have followed the steps in
[Get Started on Linux with CMake](./getting_started_linux_cmake.md).
### Install Android NDK
Android NDK provides compiler toolchains for compiling C/C++ code to target
Android. You can download it
[here](https://developer.android.com/ndk/downloads). We recommend to download
the latest release; the steps in following sections may assume that.
Alternatively, if you have installed
[Android Studio](https://developer.android.com/studio), you can follow
[this guide](https://developer.android.com/studio/projects/install-ndk) to
install Android NDK.
After downloading, it is recommended to `export` the `ANDROID_NDK` environment
variable pointing to the directory in your shell's rc file.
### Install Android Debug Bridge (ADB)
Search your Linux distro's package manager to install `adb`. For example, on
Ubuntu:
```shell
$ sudo apt install adb
```
## Build
Configure:
```shell
# Assuming in IREE source root
$ cmake -G Ninja -B build-android/ \
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI="arm64-v8a" -DANDROID_PLATFORM=android-29 \
-DIREE_BUILD_COMPILER=OFF -DIREE_BUILD_TESTS=OFF -DIREE_BUILD_SAMPLES=OFF \
-DIREE_HOST_C_COMPILER=`which clang` -DIREE_HOST_CXX_COMPILER=`which clang++`
```
* The above configures IREE to cross-compile towards 64-bit
(`-DANDROID_ABI="arm64-v8a"`) Android 10 (`-DANDROID_PLATFORM=android-29`).
This may require the latest Android NDK release. You can choose the suitable
[`ANDROID_ABI`](https://developer.android.com/ndk/guides/cmake#android_abi)
and
[`ANDROID_PLATFORM`](https://en.wikipedia.org/wiki/Android_version_history)
for your target device. You can also refer to Android NDK's
[CMake documentation](https://developer.android.com/ndk/guides/cmake) for
more toolchain arguments.
* Building IREE compilers, tests, and samples for Android is not supported at
the moment; they will be enabled soon.
* We need to define `IREE_HOST_{C|CXX}_COMPILER` to Clang here because IREE
does [not support](https://github.com/google/iree/issues/1269) GCC well at
the moment.
Build all targets:
```shell
$ cmake --build build-android/
```
## Test on Android
Make sure you
[enable developer options and USB debugging](https://developer.android.com/studio/debug/dev-options#enable)
for your Android device.
Connect your Android device to the development machine and make sure you can see
the device when:
```shell
$ adb devices
List of devices attached
XXXXXXXXXXX device
```
### VMLA HAL backend
Translate a source MLIR into IREE module:
```shell
# Assuming in IREE source root
$ build-android/host/bin/iree-translate -- \
-iree-mlir-to-vm-bytecode-module \
-iree-hal-target-backends=vmla \
iree/tools/test/simple.mlir \
-o /tmp/simple-vmla.vmfb
```
Then push the IREE runtime executable and module to the device:
```shell
$ adb push iree/tools/iree-run-module /data/local/tmp/
$ adb push /tmp/simple-vmla.vmfb /data/local/tmp/
```
Log into Android:
```shell
$ adb shell
android $ cd /data/local/tmp/
android $ ./iree-run-module -driver=vmla -input_file=simple-vmla.vmfb -entry_function=abs -inputs="i32=-5"
EXEC @abs
i32=5
```
### Vulkan HAL backend
Please make sure your Android device is Vulkan capable. Vulkan is supported on
Android since 7, but Android 10 is our primary target at the moment.
Translate a source MLIR into IREE module:
```shell
# Assuming in IREE source root
$ build-android/host/bin/iree-translate -- \
-iree-mlir-to-vm-bytecode-module \
-iree-hal-target-backends=vulkan-spirv \
iree/tools/test/simple.mlir \
-o /tmp/simple-vulkan.vmfb
```
Then push the IREE runtime executable and module to the device:
```shell
$ adb push iree/tools/iree-run-module /data/local/tmp/
$ adb push /tmp/simple-vulkan.vmfb /data/local/tmp/
```
Log into Android:
```shell
$ adb shell
android $ cd /data/local/tmp/
android $ ./iree-run-module -driver=vulkan -input_file=simple-vulkan.vmfb -entry_function=abs -inputs="i32=-5"
EXEC @abs
i32=5
```
#### Common issues
##### Vulkan function `vkCreateInstance` not available
This can happen on Android devices with ARM Mali GPUs, where there is only one
monolithic driver (`/vendor/lib[64]/libGLES_mali.so`) and the vulkan vendor
driver (`/vendor/lib[64]/hw/vulkan.*.so`) is just a symlink to it. This causes
problems for Vulkan device enumeration under `/data/local/tmp/`. A known
workaround is to copy the `libGLES_mali.so` library under `/data/local/tmp/` and
rename it as `libvulkan.so` and then prefix `LD_LIBRARY_PATH=/data/local/tmp`
when invoking IREE executables.