На дворе февраль 2021 года. Как обычно в сети полно инструкций на тему компиляции программ на Rust для Android, вот только как обычно бывает в мире Rust, большинство из них устарели. Поэтому решил собрать всё в одном месте чтобы самому не забыть. Описанный ниже способ подразумевает что кода на Java не будет совсем.
Начать надо с установки Android SDK и Android NDK. За меня это сделала IntelliJ Idea. Можно обойтись и вообще без IDE, скачав утилиты командной строки с официальной страницы и воспользовавшись утилитой sdkmanager для установки SDK и NDK.
Далее нужно прописать несколько переменных окружения. У меня они выглядят вот так:
export ANDROID_SDK_ROOT=/opt/android/sdk
export ANDROID_NDK_ROOT=$ANDROID_SDK_ROOT/ndk/22.0.7026061
export PATH=$PATH:$ANDROID_SDK_ROOT/platform-tools:$ANDROD_NDK_ROOT
В переменной ANDROID_NDK_ROOT нужно указать тот номер версии NDK, который установлен на диске.
Теперь можно приступать к настройке Rust. Благо она очень простая. В первую очередь нужно установить компиляторы для нужных платформ, например такие:
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
После этого надо поставить утилиту cargo apk:
cargo install cargo-apk
На этом этапе Rust должен быть полностью готов к сборке программ для Android. Чтобы убедиться в этом можно откомпилировать небольшой пример. Он находится по этой ссылке, бранч Android: https://github.com/adrien-ben/vulkan-tutorial-rs/tree/android. Очень важно убедиться что скачан будет именно бранч Android, иначе не заработает.
Для сборки надо запустить команду
cargo apk build
Результатом сборки будет файл target/release/apk/Vulkam Tutorial Rust.apk. Утилита cargo apk позволяет так же легко запускать программы на подключенном к компьютеру устройстве. Это делается командой
cargo apk run
По умолчанию компилируется отладочная версия программы. Чтобы откомпилировать и запустить релизную версию нужно добавить параметр –release в конце команды cargo apk:
cargo apk run --release
Иногда запуск программы намертво подвисает. В таком случае надо переподключить устройство к компьютеру. Если это не помогло, то надо вручную удалить программу на устройстве.
Для просмотра логов запустите в консоле следующую команду (этот пример для Linux, в Windows кавычки не нужны):
adb logcat RustStdoutStderr:D '*:S'
Если вдруг этот пример успешно откомпилируется но не заработает, то возможно ваш телефон не поддерживает Vulkan. Его должны поддерживать все более-менее современные телефоны, но мало ли что… Попробуйте в таком случае использовать какой-нибудь другой пример.
Бывают ситуации когда нужно откомпилировать на Rust только одну библиотеку, которая затем будет использоваться из программы на Java. В таком случае команда cargo apk является избыточной. Для сборки библиотеки для одной платформы можно ввести следующую команду:
cargo build --target=aarch64-linux-android
К сожалению, в определенных условиях это может не сработать. Я наткнулся на баг, из-за которого не вызывается линковщик целевой платформы, а вызывается обычный системный линковщик. Он разумеется не может сделать корректную библиотеку для Андроида. Чтобы решить проблему, надо создать у себя в домашнем каталоге файл .cargo/config.toml с путями к линковщикам. Вот пример конфига для Линукса:
[target.i686-linux-android]
linker = "/opt/android/sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android30-clang"
[target.x86_64-linux-android]
linker = "/opt/android/sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/bin/x86_64-linux-android30-clang"
[target.aarch64-linux-android]
linker = "/opt/android/sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang"
[target.armv7-linux-androideabi]
linker = "/opt/android/sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi30-clang"
А теперь аналогичный конфиг для Windows. Обратите внимание на то, что на конце путей добавляется суффикс .cmd. Очень важно про него не забывать, так как без него не заработает:
[target.i686-linux-android]
linker = "c:/sdk/android/sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/windows-x86_64/bin/i686-linux-android30-clang.cmd"
[target.x86_64-linux-android]
linker = "c:/sdk/android/sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/windows-x86_64/bin/x86_64-linux-android30-clang.cmd"
[target.aarch64-linux-android]
linker = "c:/sdk/android/sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android30-clang.cmd"
[target.armv7-linux-androideabi]
linker = "c:/sdk/android/sdk/ndk/22.1.7171670/toolchains/llvm/prebuilt/windows-x86_64/bin/armv7a-linux-androideabi30-clang.cmd"
Это укажет явно какой линковщик надо использовать для каждой перечисленной платформы. Путь к NDK в каждом конкретном случае скорее всего будет иным, но суть останется та же.