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

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

Разработка и компиляция кросс‑платформенных приложений в Termux: настройка NDK, CMake и clang для Android‑Linux

Профессиональная статья о сборке кросс‑платформенных проектов в Termux: установка NDK, настройка CMake и clang, примеры toolchain и практические шаги для Android‑Linux.

Автор: Усачёв Денис Евгеньевич, ведущий эксперт РыбинскЛАБ.

Введение: зачем собирать кросс‑платформенные проекты прямо в Termux

Termux позволяет превратить Android‑устройство в удобную среду разработки и сборки под Linux‑подобную командную строку. На практике это особенно полезно для кросс‑платформенных проектов на C/C++: вы пишете код, компилируете его под целевую платформу, а затем переносите артефакты на устройство или в репозиторий. В связке Android NDK + CMake + clang можно собирать нативные библиотеки (.so) и небольшие CLI‑утилиты, сохраняя привычный workflow.

Ниже — практическое руководство: как подготовить toolchain, настроить CMake и организовать сборку под популярные Android‑ABI (arm64‑v8a, armeabi‑v7a, x86_64 и т.д.). Материал ориентирован на легальную разработку и компиляцию собственных проектов.

Требования и подготовка окружения в Termux

Перед началом проверьте базовую систему и обновите пакеты. В Termux используйте репозиторий F-Droid/встроенные пакеты (официально рекомендованный сценарий зависит от вашей версии Termux):

pkg update && pkg upgrade

Установим базовые инструменты сборки и отладочный набор:

pkg install -y git curl wget unzip tar build-essential cmake ninja clang lld pkg-config

Важно: clang в Termux может использоваться для сборки «локальных» Linux‑частей. Для сборки под Android мы будем опираться на clang из NDK. Termux‑clang при этом может оставаться полезным для вспомогательных этапов.

Установка Android NDK в Termux

Есть два корректных подхода: (1) скачать NDK архивом, (2) использовать собственные средства хранения/доступа к NDK на устройстве. Удобнее всего скачать конкретную версию NDK и распаковать в рабочую директорию.

Создайте рабочий каталог и скачайте NDK:

mkdir -p ~/android-sdk ~/work
cd ~/work

Пример загрузки (подставьте актуальную ссылку на NDK rxx):

wget -O ndk.zip "https://dl.google.com/android/repository/android-ndk-r26b-linux.zip"
unzip ndk.zip -d ~/android-sdk

После распаковки обычно появится каталог вида ~/android-sdk/android-ndk-r26b. Проверьте наличие:

ls ~/android-sdk/

Если ваш NDK распакован под именем директории иначе — скорректируйте пути в дальнейших командах.

Подготовка переменных для NDK, toolchain и ABI

Ключевая часть кросс‑сборки — правильный toolchain. В NDK поддерживаются разные ABI и платформы. Обычно вы выбираете:

  • ABI: arm64-v8a, armeabi-v7a, x86_64 и др.
  • API level: например, 21 или выше (для совместимости).
  • Стандартный sysroot и компилятор clang из NDK.

Сформируем удобные переменные. Например, для arm64‑v8a:

export NDK_HOME="$HOME/android-sdk/android-ndk-r26b"
export ANDROID_API=26
export TARGET_ABI=arm64-v8a

Проверим наличие clang внутри NDK:

ls "$NDK_HOME/toolchains/llvm/prebuilt"

Внутри будет директория с именем, зависящим от хоста. Для Android‑устройств чаще встречаются сборки под linux‑вариант. Например:

ls "$NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64"

Определим PREBUILT_HOST автоматически (вручную тоже можно):

export PREBUILT_HOST="linux-x86_64"
export LLVM_BIN="$NDK_HOME/toolchains/llvm/prebuilt/$PREBUILT_HOST/bin"

Убедимся, что clang существует:

$LLVM_BIN/clang --version

Генерация toolchain-файла для CMake

CMake упрощает кросс‑компиляцию, если предоставить toolchain file. Для Android можно либо использовать готовый модуль NDK, либо явно задать параметры. Ниже — практичный вариант toolchain‑файла.

Создайте файл android-toolchain.cmake в корне проекта или в ~/work. Пример (универсальный шаблон, где ABI и API берутся из переменных):

cat > android-toolchain.cmake <<'EOF'
# Android toolchain for CMake

set(CMAKE_SYSTEM_NAME Android)

# Внешние параметры
set(NDK_HOME "$ENV{NDK_HOME}")
set(ANDROID_API "$ENV{ANDROID_API}")
set(TARGET_ABI "$ENV{TARGET_ABI}")
set(PREBUILT_HOST "$ENV{PREBUILT_HOST}")

set(LLVM_TRIPLE "aarch64-linux-android")
if(TARGET_ABI STREQUAL "arm64-v8a")
  set(LLVM_TRIPLE "aarch64-linux-android")
elseif(TARGET_ABI STREQUAL "armeabi-v7a")
  set(LLVM_TRIPLE "armv7a-linux-androideabi")
elseif(TARGET_ABI STREQUAL "x86_64")
  set(LLVM_TRIPLE "x86_64-linux-android")
elseif(TARGET_ABI STREQUAL "x86")
  set(LLVM_TRIPLE "i686-linux-android")
endif()

set(CMAKE_ANDROID_ARCH_ABI ${TARGET_ABI})
set(CMAKE_ANDROID_NDK ${NDK_HOME})
set(CMAKE_ANDROID_API ${ANDROID_API})

# Указываем компилятор clang из NDK
set(CMAKE_C_COMPILER   "${NDK_HOME}/toolchains/llvm/prebuilt/${PREBUILT_HOST}/bin/${LLVM_TRIPLE}${ANDROID_API}-clang")
set(CMAKE_CXX_COMPILER "${NDK_HOME}/toolchains/llvm/prebuilt/${PREBUILT_HOST}/bin/${LLVM_TRIPLE}${ANDROID_API}-clang++")

# sysroot и флаги обычно подхватываются через CMAKE_ANDROID_NDK.
# Но можно добавить явные настройки при необходимости.
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

EOF

Обратите внимание: тройка LLVM_TRIPLE и суффикс ${ANDROID_API} зависят от NDK. Если у вас окажется несоответствие, проверьте точные имена clang через команду в директории .../bin. Для корректности всегда лучше сверить реальные бинарники.

Структура проекта и подготовка исходников

Рассмотрим типовой пример: у вас есть CMake‑проект с CMakeLists.txt. Для кросс‑сборки важно, чтобы вы:

  • использовали add_library/add_executable с корректными исходниками;
  • избегали жестко заданных системных путей;
  • применяли target_include_directories и зависимости через target_link_libraries.

Если проект использует собственные зависимости, учитывайте, что в Android окружении они должны быть собраны или доступны как prebuilt под вашу ABI.

Пример CMakeLists.txt для сборки библиотеки

Шаблон минимальной библиотеки:

cat > CMakeLists.txt <<'EOF'
cmake_minimum_required(VERSION 3.22)
project(mini-ndk-lib LANGUAGES C CXX)

add_library(mini SHARED
  src/mini.c
)

target_compile_features(mini PRIVATE c_std_11)

# Опционально: дополнительные флаги
# set_target_properties(mini PROPERTIES C_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON)

EOF

Создайте исходник src/mini.c:

mkdir -p src
cat > src/mini.c <<'EOF'
#include <stdio.h>

int mini_value(void) {
    return 42;
}

EOF

Сборка под Android в Termux: запуск CMake и Ninja

Организуйте build‑каталог отдельно для каждой ABI, чтобы не смешивать артефакты.

Например, для arm64‑v8a:

export BUILD_DIR="~/work/build-${TARGET_ABI}"
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"

cd "$BUILD_DIR"

cmake \
  -G Ninja \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_TOOLCHAIN_FILE="$HOME/work/android-toolchain.cmake" \
  -DANDROID_STL=c++_shared \
  "$HOME/work/your-project"

ninja -v

Важный момент: если ваш проект на C без C++, не нужно задавать ANDROID_STL. Но для C++ — обычно нужно, чтобы корректно выбрать стандартную библиотеку рантайма (например, c++_shared или c++_static).

Список ABI и типичные отличия

Для расширения охвата просто меняйте TARGET_ABI. Например:

for ABI in arm64-v8a armeabi-v7a x86_64; do
  export TARGET_ABI="$ABI"
  export BUILD_DIR="~/work/build-${ABI}"
  rm -rf "$BUILD_DIR"
  mkdir -p "$BUILD_DIR"
  cd "$BUILD_DIR"

  cmake -G Ninja \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_TOOLCHAIN_FILE="$HOME/work/android-toolchain.cmake" \
    "$HOME/work/your-project"

  ninja -v
done

Если сборка падает на этапе линковки — чаще всего проблема связана с несовпадением ABI зависимостей, неправильным API level или тем, что ABI/тройка не соответствует доступным бинарникам clang внутри NDK.

Вывод артефактов и размещение .so

По умолчанию CMake складывает результаты в подкаталоги build‑директории. Для удобства полезно знать где именно лежит mini.so. Проверьте:

find "$BUILD_DIR" -maxdepth 4 -name ".so"

Далее артефакты можно поместить в структуру Android проекта (например, app/src/main/jniLibs/<abi>/) или использовать для интеграции через Gradle/другие механизмы. В рамках Termux часто достаточно сохранить .so в папку, синхронизируемую с вашим репозиторием.

Отладка сборки: распространенные ошибки и быстрые проверки

1) Ошибка “C compiler cannot create executables”

Это частая проблема при кросс‑сборке. Она может возникнуть, если CMake пытается запускать собранный бинарник на хосте. Решение — корректно задать toolchain и параметры Android через android-toolchain.cmake. Для Android кросс‑сборки обычно это автоматически предотвращается правильно настроенным toolchain.

2) Не находится clang

Проверьте точное имя файла clang в директории $LLVM_BIN:

ls "$LLVM_BIN" | grep clang | head

И скорректируйте LLVM_TRIPLE и суффикс ${ANDROID_API} в toolchain‑файле.

3) Несовместимость ABI зависимостей

Если вы линковали внешнюю библиотеку, убедитесь, что её .so собрана под тот же ABI и тот же уровень/ABI‑совместимость.

Автоматизация: сборка “Android‑Linux” как кросс‑процесс

Под “Android‑Linux” в этом контексте обычно понимают процесс, где вы ведёте сборку в Linux‑подобной среде Termux (Android как хост), но получаете нативные артефакты для Android ABI. Практически вы организуете pipeline как “build on Android-host → output for Android target”.

Автоматизируйте:

  • выбор ABI и API;
  • создание build‑директорий по ABI;
  • сохранение артефактов в единый каталог;
  • ведение логов (например, ninja -v > build.log 2>&1).

Пример структуры вывода:

export OUT_DIR="$HOME/work/out"
mkdir -p "$OUT_DIR"

# после ninja копируйте найденные .so
cp -v "$BUILD_DIR"/**/libmini.so "$OUT_DIR/" 2>/dev/null || true

Про VPN: только для создания локальной сети

Если вам нужно организовать локальную сеть между устройствами разработки (например, для доступа к общему репозиторию/тестовому серверу внутри вашей сети), допускается использование VPN для создания локальной сети. Это не предназначено для обхода блокировок или иных ограничений — выбирайте легальные и безопасные сценарии.

Заключение

Termux отлично подходит для кросс‑платформенной разработки: вы можете настроить Android NDK, подготовить toolchain для CMake и собирать нативные библиотеки под разные ABI с использованием clang из NDK. Главное — строго следить за соответствием ABI/API и проверять реальные имена бинарников в NDK, а также аккуратно отделять build‑директории по архитектурам.

Если хотите ускорить настройку под ваш проект (включая интеграцию зависимостей, поддержку нескольких ABI и оптимизации для Release/Debug), обратитесь за помощью в РыбинскЛАБ. Мы поможем выстроить сборочный пайплайн и довести окружение до стабильной работы.

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

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

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

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