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

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

Кросс‑компиляция C/C++ проектов в Termux с использованием clang и ndk‑toolchain

Пошаговое руководство по кросс-компиляции C/C++ в Termux: установка clang, настройка NDK toolchain, сборка для Android‑архитектур и типовые проблемы.

Терминальная среда Termux отлично подходит для разработки и сборки проектов, но когда речь заходит о кросс‑компиляции C/C++ под Android (ARMv7/ARM64/x86/x86_64), возникает вопрос: как корректно использовать clang и ndk-toolchain. В этой статье мы разберём практический и системный подход — от подготовки инструментов до сборки типового проекта и диагностики ошибок.

Зачем нужна кросс‑компиляция в Termux

В Termux вы можете компилировать программы под архитектуру вашего устройства, но при кросс‑компиляции можно:

  • собрать бинарники для другой архитектуры (например, ARM64 на x86_64 устройствах и наоборот);
  • фиксировать инструментальную цепочку (версии clang/stdlib/ABI);
  • использовать стандартные параметры Android NDK (sysroot, API level, ABI);
  • ускорить сборку и повысить воспроизводимость.

Что подготовить заранее

Нам понадобятся:

  • Termux (желательно актуальная версия);
  • Android NDK (комплект инструментов с ndk-build/clang toolchain);
  • clang в Termux (в некоторых сценариях можно собрать и без него, но для унификации используем подход с clang);
  • базовые пакеты: build-essential, cmake/autotools (по проекту).

Дальше будем считать, что у вас уже скачан NDK и вы понимаете, под какую ABI хотите собирать.

Установка зависимостей в Termux

Обновите индексы пакетов и поставьте базовые инструменты:

pkg update -y
pkg upgrade -y
pkg install -y clang lld make cmake ninja autoconf automake libtool pkg-config python

Проверка, что clang доступен:

clang --version

Подключение Android NDK toolchain

Самый практичный путь — использовать clang, входящий в NDK, потому что он «знает» про Android sysroot, ABI и совместимость. Предположим, что NDK лежит в:

NDK=/data/data/com.termux/files/home/android-ndk

Вам нужно указать корректный путь к вашему NDK. Далее будем использовать переменные для API level и ABI.

Выбор ABI и API level

Android ABI задаёт таргетную архитектуру. Типичные значения:

  • arm64-v8a
  • armeabi-v7a
  • x86_64
  • x86

API level обычно выбирают в пределах 21–34 в зависимости от требований. В примерах ниже возьмём android API 24 как рабочую основу.

API=24

Концепция: sysroot и target‑triple

В NDK важно использовать правильный target‑triple (например, aarch64-linux-android) и sysroot. Обычно NDK обеспечивает это автоматически, но в ручных командных строках мы должны указать параметры явно или через готовые обёртки.

Дальше покажем два подхода:

  • через прямой вызов clang с параметрами NDK;
  • через CMake Toolchain файл (удобнее для проектов на CMake).

Подход 1: ручной clang + NDK toolchain (универсально)

Рассмотрим простейший случай: компиляция одного .c/.cpp файла. Пусть проект содержит main.cpp. Мы создадим сборочную папку и соберём бинарник под нужный ABI.

Выберите ABI. Например, arm64-v8a:

ABI=arm64-v8a

Настройте параметры для arm64:

TRIPLE=aarch64-linux-android
CLANG=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/clang
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot

Важно: путь prebuilt/linux-x86_64 зависит от того, под какой хост платформой вы распаковали NDK. Если NDK скачан на другой ОС — скорректируйте путь к prebuilt. В Termux вы обычно используете NDK из файловой системы устройства, но структура prebuilt внутри архива всё равно соответствует платформе, с которой вы распаковали NDK.

Собрать:

mkdir -p build/$ABI
$CLANG --target=$TRIPLE$API \
  --sysroot=$SYSROOT \
  -fPIC -O2 -Wall \
  -c main.cpp -o build/$ABI/main.o

$CLANG --target=$TRIPLE$API \
  --sysroot=$SYSROOT \
  build/$ABI/main.o -o build/$ABI/app \
  -Wl,--gc-sections

Если вы собираете C++ и хотите явно указать стандарт:

$CLANG --target=$TRIPLE$API --sysroot=$SYSROOT \
  -std=c++17 -O2 -fPIC -Wall \
  -c main.cpp -o build/$ABI/main.o

Подход 2: CMake Toolchain файл для кросс‑компиляции

Если ваш проект использует CMake (или вы хотите перевести сборку на CMake), то лучше создать Toolchain файл. Он позволит CMake автоматически проставить нужные параметры.

Создадим файл android-toolchain-$ABI.cmake в домашней директории Termux.

Пример для arm64-v8a:

ABI=arm64-v8a
API=24
TRIPLE=aarch64-linux-android
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot

cat > ~/android-toolchain-$ABI.cmake <<'EOF'
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 1)

# Variables injected by wrapper
set(TARGET_TRIPLE "${TRIPLE}")
set(ANDROID_API "${API}")
set(NDK_ROOT "${NDK}")
set(LLVM_PREBUILT "${LLVM_PREBUILT}")

set(CMAKE_C_COMPILER "${TOOLCHAIN}/clang")
set(CMAKE_CXX_COMPILER "${TOOLCHAIN}/clang++")

set(CMAKE_C_FLAGS "--target=${TRIPLE}${API} --sysroot=${SYSROOT}")
set(CMAKE_CXX_FLAGS "--target=${TRIPLE}${API} --sysroot=${SYSROOT}")

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

set(CMAKE_FIND_ROOT_PATH "${SYSROOT}")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
EOF

Этот скрипт содержит переменные ${TRIPLE}, ${API} и прочие, поэтому перед запуском убедитесь, что экспортировали их корректно. Если предпочитаете более «жёсткий» шаблон, можно подставить значения прямо в файл (без переменных).

Далее сборка:

mkdir -p build-cmake/$ABI
cd build-cmake/$ABI
cmake ../.. \
  -DCMAKE_TOOLCHAIN_FILE=~/android-toolchain-$ABI.cmake \
  -DCMAKE_BUILD_TYPE=Release

cmake --build . -j$(nproc)

После успешной сборки вы получите артефакты в каталоге сборки, соответствующие вашему ABI.

Проверка результатов и базовая диагностика

Первое, что стоит сделать — убедиться, что бинарник соответствует архитектуре. В Termux можно использовать file, но при необходимости установите file:

pkg install -y file
file build/$ABI/app

Типовые ошибки:

  • Не найден sysroot / ошибки libc: проверьте путь к sysroot и target‑triple.
  • Символы не находятся / несовместимость ABI: убедитесь, что собираете и линковку с тем же target.
  • Проблемы с зависимостями (zlib/openssl/etc.): соберите их также под Android (тем же ABI/API), либо подключайте корректные статические библиотеки.
  • «undefined reference to __android_log_*»: добавьте нужные системные библиотеки (часто log).

Пример: сборка статической библиотеки и линковка с Android log

Допустим, у вас есть libhello, и вы хотите линковать приложение с android log. В CMake это обычно делается так:

# CMakeLists.txt (фрагмент)
add_library(hello STATIC hello.cpp)

add_executable(app main.cpp)
target_link_libraries(app PRIVATE hello log)

Если вы собираете вручную через clang, то на этапе линковки нужно добавить -llog и корректные флаги линковщика. Конкретные детали зависят от проекта, но общий принцип такой:

$CLANG --target=$TRIPLE$API --sysroot=$SYSROOT \
  build/$ABI/main.o build/$ABI/libhello.a \
  -llog -Wl,--gc-sections \
  -o build/$ABI/app

Рекомендации для воспроизводимости

  • Фиксируйте версию NDK и API level (например, API=24).
  • Храните toolchain файлы в папке проекта или рядом с ними.
  • Держите отдельные build-каталоги по ABI: build/arm64-v8a, build/armeabi-v7a.
  • Собирайте все зависимости под те же ABI/API (или используйте заведомо подготовленные Android-версии).

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

Частые вопросы

Можно ли использовать clang из Termux вместо clang из NDK?

Технически иногда можно, но чаще проще и надёжнее использовать clang/clang++ из самого NDK, чтобы гарантировать корректные пути к sysroot и совместимость с Android.

Почему CMake не находит заголовки/библиотеки?

Обычно потому что включены неверные CMAKE_FIND_ROOT_PATH и режимы поиска. Toolchain файл должен ограничивать поиск в сторону sysroot для target-библиотек и заголовков.

Как ускорить сборку?

Используйте -j$(nproc) и режим Release. Для CMake также включайте Ninja, если применимо.

Заключение

Кросс‑компиляция C/C++ в Termux с использованием clang и ndk‑toolchain становится предсказуемой, если вы правильно задаёте target‑triple, sysroot и собираете зависимости согласованно по ABI и API level. Для универсальных задач удобен прямой вызов clang, а для проектов на CMake — toolchain файл, который стандартизирует параметры сборки.

Если вам нужна помощь с настройкой toolchain под ваш проект, портированием сборки или подбором конфигурации под нужные ABI — обращайтесь в РыбинскЛАБ. Мы поможем организовать стабильный процесс кросс‑сборки и диагностику проблем на вашей стороне.

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

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

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

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