Termux — один из самых удобных инструментов для практической разработки прямо на Android. Однако когда задача выходит за рамки «просто собрать бинарник», появляется потребность в кросс‑компиляции: собрать артефакты для нужной архитектуры (arm64-v8a, armeabi-v7a и т.д.), подготовить релизные сборки и контролировать цепочку инструментов.
Ниже — практический, прикладной подход к разработке и компиляции приложений на Rust и Go в Termux с настройкой кросс‑компиляторов, ориентированный на воспроизводимые сборки.
Что подготовить в Termux
Перед настройкой кросс‑компиляции важно иметь базовую «гигиену» окружения: обновить пакеты, поставить необходимые инструменты (компиляторы, линкеры, build-утилиты) и убедиться, что у вас определяются target-архитектуры.
Запустите терминал Termux и выполните обновление:
pkg update && pkg upgrade -yДалее поставьте базовые пакеты. Набор может отличаться в зависимости от версии Termux, но логика такая: компилятор/линкер, build-утилиты, curl/ca-certificates и необходимые библиотеки.
pkg install -y git curl ca-certificates clang lld llvm binutils make cmake pkg-configДля кросс‑сборок обычно также полезны:
pkg install -y python ndk-bundleПримечание: пакет ndk-bundle может отсутствовать в конкретной конфигурации Termux или называться иначе. Если NDK недоступен в репозиториях — подойдёт установка через официальные средства или локальная поставка NDK. Важно, чтобы вы могли получить toolchain для нужной платформы.
Определение архитектуры и target в Android
Кросс‑компиляция в экосистемах Rust/Go опирается на «target тройки» и/или GOARM/GOARCH. Android в этом смысле требует аккуратности: архитектура и ABI должны совпадать с ожидаемыми параметрами.
Проверьте, что у вас видна архитектура устройства (для ориентирования):
uname -mДля Android-проектов часто используются следующие соответствия:
- arm64-v8a →
aarch64-linux-android - armeabi-v7a →
armv7a-linux-androideabi(и обычно GOARM=7 для Go) - x86_64 →
x86_64-linux-android - x86 →
i686-linux-android
Задача кросс‑компилятора — сформировать правильные флаги компиляции/линковки и предоставить компилятор/линкер из toolchain.
Rust в Termux: базовая сборка и переход к кросс‑компиляции
Установите Rust toolchain (если он ещё не установлен) через официальную установку rustup. В большинстве случаев rustup работает корректно в Termux.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shПосле установки примените профиль (или перезапустите shell):
source ~/.cargo/envПроверьте:
rustc --version && cargo --versionДля базовой сборки проекта Rust в Termux достаточно:
cargo build --releaseНо для кросс‑компиляции нужно:
- добавить target в rustup;
- настроить ссылку на Android NDK toolchain через конфигурацию cargo (или через .cargo/config.toml);
- при необходимости — задать арендованные линки/включения.
Добавим target (пример для aarch64-linux-android). Сначала определите, под какую архитектуру вы собираете.
rustup target add aarch64-linux-androidСоздайте конфиг Cargo для Android toolchain. Удобное место — .cargo/config.toml в корне проекта или в домашнем каталоге. Пример структуры:
mkdir -p .cargoДалее создайте .cargo/config.toml. Пример для aarch64:
cat > .cargo/config.toml <<'EOF'
[target.aarch64-linux-android]
ar = "llvm-ar"
linker = "ld.lld"
rustflags = [
"-C", "link-arg=--no-warn-shared-textrel",
]
EOFВажно: значения ar и linker должны соответствовать вашему окружению. Если вы используете NDK, часто требуется точный путь к toolchain. Поэтому ниже — более надёжный путь: подтянуть компиляторы из NDK через переменные среды и/или конкретные абсолютные команды.
Если у вас есть NDK и известен путь, настройте переменные. Например, предположим что NDK лежит в $HOME/Android/Sdk/ndk-bundle (путь может отличаться):
export ANDROID_NDK_HOME="$HOME/Android/Sdk/ndk-bundle"Выставьте API level (например, 21 — минимально совместимый для arm64 в большинстве практик; конкретные требования — на вашу задачу):
export ANDROID_API=21Далее можно использовать toolchain префиксы из NDK. Примерно:
export AR="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar"
export CC="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android${ANDROID_API}-clang"
export CXX="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android${ANDROID_API}-clang++"
export LD="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/ld.lld"Если prebuilt директория отличается (например, для другого хоста), подберите соответствующую ветку. Ключевой момент — получить корректный llvm toolchain под ваш хост в Termux.
Затем в .cargo/config.toml укажите:
cat > .cargo/config.toml <<'EOF'
[target.aarch64-linux-android]
ar = "llvm-ar"
linker = "ld.lld"
EOFИ запустите:
cargo build --release --target aarch64-linux-androidЧтобы проверить, что бинарник действительно под нужный target:
file target/aarch64-linux-android/release/*Обычно в проекте имена исполняемых файлов отличаются. Для точности укажите конкретный файл.
Go в Termux: сборка и кросс‑компиляция под Android
Go удобно тем, что кросс‑компиляция во многом задаётся стандартными переменными: GOOS, GOARCH и (для 32-битных ARM) GOARM.
Установите Go в Termux:
pkg install -y golangПроверьте:
go versionПример базовой сборки:
go build -trimpath -o app ./cmd/appДля кросс‑сборки в Android обычно:
- GOOS =
android - GOARCH =
arm64илиarmили386/amd64 - GOARM =
7(если GOARCH=arm)
Например, сборка для arm64-v8a:
GOOS=android GOARCH=arm64 CGO_ENABLED=1
CC="$CC"
go build -trimpath -ldflags="-s -w" -o app-android-arm64 ./cmd/appДля armeabi-v7a:
GOOS=android GOARCH=arm GOARM=7 CGO_ENABLED=1
CC="$CC"
go build -trimpath -ldflags="-s -w" -o app-android-armv7 ./cmd/appКлючевой момент: когда CGO_ENABLED=1, Go будет использовать внешний компилятор для C-частей зависимостей. Поэтому переменная CC должна ссылаться на Android NDK toolchain (как в Rust-блоке). Если ваш проект полностью pure Go, иногда можно поставить CGO_ENABLED=0 и избежать NDK, но это зависит от зависимостей.
Если вы хотите собрать без CGO (только pure Go), используйте:
GOOS=android GOARCH=arm64 CGO_ENABLED=0
go build -trimpath -ldflags="-s -w" -o app-android-arm64 ./cmd/appПроверка артефакта:
file app-android-arm64Для Android бинарники могут выглядеть по-разному, но file помогает удостовериться в архитектуре/формате.
Единый подход: один скрипт сборки для нескольких target
Практика показывает, что удобнее иметь один «универсальный» скрипт, который последовательно собирает нужные архитектуры. Это повышает воспроизводимость и снижает ошибки.
Пример shell-скрипта для Go под несколько архитектур (с использованием NDK и CC для CGO):
cat > build-go-android.sh <<'EOF'
#!/data/data/com.termux/files/usr/bin/bash
set -euo pipefail
ANDROID_NDK_HOME="${ANDROID_NDK_HOME:?Set ANDROID_NDK_HOME}"
ANDROID_API="${ANDROID_API:-21}"
# toolchain bin (путь host-хоста может отличаться; подставьте ваш)
TOOLCHAIN_BIN="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin"
build_one () {
local arch="$1"
local goarch="$2"
local goarm="${3:-}"
local cc
if [ "$arch" = "arm64" ]; then
cc="$TOOLCHAIN_BIN/aarch64-linux-android${ANDROID_API}-clang"
elif [ "$arch" = "armv7" ]; then
cc="$TOOLCHAIN_BIN/armv7a-linux-androideabi${ANDROID_API}-clang"
else
echo "Unsupported arch: $arch" >&2
exit 1
fi
local out="app-android-${arch}"
if [ -n "$goarm" ]; then
GOOS=android GOARCH="$goarch" GOARM="$goarm" CGO_ENABLED=1 CC="$cc"
go build -trimpath -ldflags="-s -w" -o "$out" ./cmd/app
else
GOOS=android GOARCH="$goarch" CGO_ENABLED=1 CC="$cc"
go build -trimpath -ldflags="-s -w" -o "$out" ./cmd/app
fi
}
build_one arm64 arm64
build_one armv7 arm 7
echo "Done."
EOF
chmod +x build-go-android.shЗапуск:
export ANDROID_NDK_HOME="$HOME/Android/Sdk/ndk-bundle"
export ANDROID_API=21
./build-go-android.shДля Rust аналогичный подход реализуют через повторные вызовы cargo build с разными --target, а конфиги обычно дополняют матрицей по target.
Практические советы по стабильной кросс‑компиляции
- Фиксируйте версии Rust toolchain и Go. Для Rust — use
rust-toolchain.toml. Для Go — pin версию вgo.modи документируйте её. - Проверяйте API level. Слишком высокий API level может сузить совместимость, слишком низкий — сломать сборку некоторых зависимостей.
- Держите консистентные линкеры. В Rust для Android важно, чтобы
linkerдействительно соответствовал target. - Включайте “release” и добавляйте оптимизации только тогда, когда всё уже стабильно собирается в dev-режиме.
- Логи важнее догадок: если сборка падает, сначала смотрите ошибки компоновки (linker) и только потом корректируйте библиотеки.
Заключение
Разработка и компиляция приложений на Rust и Go в Termux становится по-настоящему эффективной, когда вы выстраиваете контролируемую цепочку кросс‑компилятора: правильно добавляете target, настраиваете linker/CC, учитываете API level и проверяете артефакты. Следуя приведённым шагам, вы сможете собирать релизные бинарники под нужные Android архитектуры и уверенно переносить сборки между окружениями.
Если хотите ускорить настройку под ваши реальные проекты (зависимости, CGO, нестандартные кривая сборки Rust/crates, матрица target), РыбинскЛАБ поможет: консультации и сопровождение по разработке в Termux, настройке кросс‑компиляции Rust/Go и подготовке воспроизводимых релизов.