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 с помощью CMake и Meson

Пошаговое руководство по портированию C/C++ библиотек в Termux: сборка через CMake и Meson, работа с нестандартными зависимостями, sysroot, toolchain, типовые ошибки и рекомендации для стабильных билдов в РФ.

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

Зачем портировать C/C++ в Termux и что обычно «ломается»

Termux удобен для разработки и тестирования, но при переносе библиотек C/C++ с «обычной» настольной сборки на мобильную среду часто возникают предсказуемые проблемы: отличия в ABI, отсутствие нужных системных библиотек, нетривиальные зависимости (например, сборка из исходников вместо пакета), различия в путях к include/lib, а также особенности динамической загрузки на Android.

В этой статье разберём практический подход к портированию библиотек с нестандартными зависимостями в Termux с опорой на CMake и Meson: как настроить toolchain, как организовать зависимости, как заставить сборочные системы находить нужные заголовки/библиотеки и как системно устранять типовые ошибки.

Подготовка Termux: базовые зависимости и ориентиры

Начните с актуального окружения и инструментов сборки. Для Termux удобнее всего использовать репозитории пакетов Termux, а нестандартные зависимости — собирать в отдельный префикс (например, в $PREFIX или в выделенную директорию /data/data/.../prefix).

pkg update
pkg upgrade
pkg install clang make ninja-build cmake meson pkg-config git python curl

Если библиотека зависит от дополнительных компонентов (например, libssl, libcurl, zlib, libpng), сначала попытайтесь поставить их через pkg install. Когда пакета нет или требуется нестандартная версия/конфигурация — переходите к сборке из исходников.

Общий принцип: все зависимости должны попадать в один «префикс»

Чтобы сборка в Termux была воспроизводимой, избегайте «смешивания» артефактов из разных источников в произвольных местах. Практика: собирайте зависимости с одним префиксом (например, $HOME/prefix) и затем собирайте целевую библиотеку, указывая:

  • пути поиска заголовков: -I / переменные CPATH, CMAKE_INCLUDE_PATH;
  • пути поиска библиотек: -L / переменные LIBRARY_PATH, CMAKE_LIBRARY_PATH;
  • и переменную окружения для компоновщика/линковщика при необходимости.

В Termux обычно используется $PREFIX (обычно /data/data/com.termux/files/usr). Однако если вы хотите отделить «ваши» библиотеки от системных, создайте отдельный префикс. Пример:

export PREFIX_LOCAL="$HOME/prefix"
mkdir -p "$PREFIX_LOCAL"/ {include,lib,bin,share} 

Дальше вы будете собирать зависимости с установкой в этот префикс.

Toolchain и sysroot: как не наступать на ABI

На Android/Termux критично собирать под «правильную» архитектуру. В Termux обычно доступны соответствующие компиляторы clang. Для большинства случаев достаточно использовать стандартные переменные окружения Termux и настройки, которые поддерживает ваша сборочная система.

Однако при нестандартных сценариях (например, когда библиотека пытается использовать системные пути Linux, которых нет в Android) может понадобиться toolchain-файл. Для CMake и Meson подход отличается.

Портирование через CMake: базовая схема

Для CMake в Termux обычно удобен out-of-source build. Библиотека может требовать:

  • указать -DCMAKE_INSTALL_PREFIX для установки в нужный префикс;
  • помочь найти зависимости через PKG_CONFIG_PATH, CMAKE_PREFIX_PATH, CMAKE_LIBRARY_PATH;
  • при необходимости отключить тесты/утилиты, если они тянут лишние зависимости.

Шаблон:

export PREFIX_LOCAL="$HOME/prefix"
export PKG_CONFIG_PATH="$PREFIX_LOCAL/lib/pkgconfig:$PKG_CONFIG_PATH"
export CMAKE_PREFIX_PATH="$PREFIX_LOCAL:$CMAKE_PREFIX_PATH"

# Пример: сборка целевой библиотеки
cd /path/to/libsrc
mkdir -p build-cmake && cd build-cmake

cmake .. \
  -G Ninja \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX="$PREFIX_LOCAL" \
  -DBUILD_SHARED_LIBS=ON \
  -DBUILD_TESTING=OFF \
  -DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH" \
  -DCMAKE_LIBRARY_PATH="$PREFIX_LOCAL/lib" \
  -DCMAKE_INCLUDE_PATH="$PREFIX_LOCAL/include"

ninja
ninja install

Ключевой момент: PKG_CONFIG_PATH и CMAKE_PREFIX_PATH — первые инструменты, к которым стоит обращаться, если CMake не находит библиотеку.

Как «лечить» поиск зависимостей в CMake

Часто проблема выглядит так: CMake пишет, что не найден Foo или FooConfig.cmake, хотя вы его уже собрали. Варианты решения:

  • pkg-config: убедитесь, что у зависимости есть .pc и что он установлен в $PREFIX_LOCAL/lib/pkgconfigPKG_CONFIG_PATH содержит этот путь).
  • конфигурационные файлы CMake: если есть FooConfig.cmake, то проверьте, куда они установлены (часто lib/cmake/Foo или share/Foo). Тогда CMAKE_PREFIX_PATH должен указывать префикс, в котором лежит lib/cmake.
  • ручные подсказки: иногда достаточно передать -DFOO_INCLUDE_DIR и -DFOO_LIBRARY (зависит от проекта).

Если проект использует кастомный модуль поиска, может помочь просмотр CMakeLists.txt и модулей в cmake/, чтобы понять, какие переменные он ожидает.

Портирование через Meson: настройка через .ini/переменные и prefix

Meson в Termux часто работает проще, особенно если вы используете pkg-config для определения зависимостей. Основной подход:

  • out-of-source build;
  • установка в --prefix (или -Dprefix в зависимости от проекта);
  • указание путей через PKG_CONFIG_PATH и/или переменные Meson (зависит от проекта).

Шаблон:

export PREFIX_LOCAL="$HOME/prefix"
export PKG_CONFIG_PATH="$PREFIX_LOCAL/lib/pkgconfig:$PKG_CONFIG_PATH"

cd /path/to/libsrc
meson setup build-meson \
  --prefix "$PREFIX_LOCAL" \
  --buildtype release \
  -Dtests=false \
  -Dexamples=false

meson compile -C build-meson
meson install -C build-meson

Если проект поддерживает флаги вроде -Ddefault_library=both или аналогичные — используйте их, но точные названия зависят от конкретного проекта.

Нестандартные зависимости: когда pkg-config не помогает

Сложнее всего, когда зависимость не предоставляет .pc файл или не устанавливает конфиги в ожидаемые директории. Тогда вам придётся:

  • собрать зависимость с нужными параметрами, чтобы установить заголовки/библиотеки в стандартные места;
  • создать недостающие метаданные (например, .pc файл) вручную;
  • или подсказать сборочной системе пути (CMake: -D..._INCLUDE_DIR, Meson: через cpp_args/link_args или через переменные проекта).

Простой и практичный способ для Meson — иногда задать параметры компилятора и линковщика на уровне конфигурации проекта, если он это поддерживает. Для CMake — часто задаются кастомные переменные.

Пример: локальная сборка зависимости в префикс

Рассмотрим универсальный сценарий: зависимость поставляется исходниками и её нужно встроить в ваш prefix.

export PREFIX_LOCAL="$HOME/prefix"
export PATH="$PREFIX_LOCAL/bin:$PATH"
export LD_LIBRARY_PATH="$PREFIX_LOCAL/lib:$LD_LIBRARY_PATH"

# Допустим, у зависимости CMake
cd /path/to/dep
mkdir -p build-dep && cd build-dep

cmake .. \
  -G Ninja \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX="$PREFIX_LOCAL" \
  -DBUILD_TESTING=OFF

ninja
ninja install

После этого целевая библиотека должна начать находить зависимость по pkg-config (если он доступен) и/или по CMAKE_PREFIX_PATH.

Динамические библиотеки на Android/Termux: проверка линковки

После сборки проверьте, что бинарники/шейред-либы корректно ссылаются на нужные .so и что они доступны во время запуска. На практике удобно смотреть зависимости через readelf или ldd (если доступно). Например:

# Локально проверьте, куда смотрит загрузчик
readelf -d /path/to/your/library.so | grep -E 'NEEDED|RPATH|RUNPATH'

# Для запуска вы можете временно задать путь к библиотекам
export LD_LIBRARY_PATH="$PREFIX_LOCAL/lib:$LD_LIBRARY_PATH"
/path/to/your/binary --help

Если проект использует RPATH/RUNPATH — настройте корректно. Иначе — управляйте LD_LIBRARY_PATH в окружении при тестах.

Типовые ошибки и что делать

  • “не найден Foo”: проверьте PKG_CONFIG_PATH и наличие foo.pc. Если fooConfig.cmake — проверьте CMAKE_PREFIX_PATH и где установлены cmake-модули.
  • несовместимая архитектура: значит зависимость собрана не под вашу ABI. В Termux убедитесь, что вы используете один и тот же toolchain и не подтягиваете бинарники с другого окружения.
  • undefined references: обычно означает, что линковщик не увидел одну из библиотек или выбрана неверная версия/режим (static/shared). Проверьте порядок линковки и опции проекта.
  • не те флаги компиляции: иногда проекты по умолчанию включают SIMD/ASM, которые не поддерживаются в вашей конфигурации. В CMake/Meson отключайте проблемные опции.

Хорошая практика: после каждого изменения пересобирать только то, что нужно, и хранить лог конфигурации (CMakeCache, meson-log) для последующего анализа.

Полезная организация проекта: скрипты сборки и кэш артефактов

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

  • deps/<name>/ — исходники и build под зависимость;
  • build/<target>/ — build целевой библиотеки;
  • prefix/ — общий префикс для установки.

А затем управляйте переменными окружения в одном месте, чтобы не было рассинхрона.

Meson vs CMake: как выбрать подход

Если проект — «современный», часто Meson быстрее даёт понятную диагностику через логи конфигурации. Если проект сложный и использует кастомные CMake-модули поиска, CMake может быть удобнее благодаря большему числу стандартов вокруг Find.cmake и *Config.cmake.

На практике нередко приходится комбинировать: зависимости собрать через один инструмент, а целевую библиотеку — через другой (или наоборот). Ключ — единый prefix и корректные метаданные (pkg-config / cmake config).

Локальная сеть через VPN (только для задач разработки/тестирования)

Иногда при разработке на Termux удобно поднимать локальное взаимодействие с ПК (например, для тестирования сервисов). Если используете VPN, делайте это только для организации локальной сети между устройством и вашим ПК, а не для обхода блокировок. Параметры зависят от выбранного VPN-решения и вашей сети.

Заключение

Портирование C/C++ библиотек в Termux с нестандартными зависимостями — это дисциплина управления префиксами, корректный поиск зависимостей (через PKG_CONFIG_PATH, CMAKE_PREFIX_PATH и установочные директории), а также системный подход к диагностики сборки. Начните с единообразного prefix, собирайте зависимости в него, затем собирайте целевой проект в out-of-source режиме. Для CMake чаще всего «магия» начинается с PKG_CONFIG_PATH и CMAKE_PREFIX_PATH, для Meson — с pkg-config и логов конфигурации.

Нужна помощь с портированием конкретной библиотеки под Termux (CMake/Meson, toolchain, нестандартные зависимости, отладка линковки и поиска пакетов)? Обратитесь в РыбинскЛАБ — мы поможем подготовить рабочий билд-процесс, консультации по конфигурации и устранение типовых проблем.

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

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

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

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