We detected you are likely not from a Russian-speaking region. Would you like to switch to the international version of the site?

  Назад к списку статей

Разработка и компиляция приложений на Rust/Go в Termux: настройка кросс‑компиляторов

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-v8aaarch64-linux-android
  • armeabi-v7aarmv7a-linux-androideabi (и обычно GOARM=7 для Go)
  • x86_64x86_64-linux-android
  • x86i686-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 и подготовке воспроизводимых релизов.

* Текст статьи подготовлен и структурирован с использованием технологий искусственного интеллекта. Проверен и доработан перед публикацией.

Нужна помощь с настройкой Termux, Linux и серверов?

Я оказываю ИТ-услуги: настройка серверов, автоматизация, безопасность, помощь с Linux и инфраструктурой. Материалы сайта — только в ознакомительных и образовательных целях.

Связаться со мной
Поддержать проект