Инструмент для кросс-сборки apptool
apptool — это инструмент для кросс-сборки пакетов, независимый от mb2
и sb2
.
Он предоставляет другой набор функций и опций.
В отличие от sb2
, который имитирует нативную компиляцию для разных архитектур,
apptool
использует реальную кросс-компиляцию
с помощью кросс-компиляторов.
Инструкция по сборке с apptool
Краткая инструкция по кросс-сборке Qt (QML) приложения для ОС Аврора с помощью SDK (BT) в Docker-контейнере. Предполагается, что Docker установлен и работает.
-
Установить Docker-образ с новым SDK.
docker pull hub.omp.ru/public/sdk-build-tools
-
Перейти в ту директорию, где лежат исходники пакета и каталог
rpm
соspec
-файлом. Например:cd <путь>/ApplicationTemplate
Команда приводится для Unix-совместимого терминала. В Linux и macOS можно использовать стандартный терминал, в Windows необходимо использовать Git Bash.
-
Минимальная команда для запуска Docker-контейнера в Linux:
docker run -it --rm -u `id -u`:`id -g` -v "$PWD":/sources -w /sources hub.omp.ru/public/sdk-build-tools
В конце команды может быть тэг, который можно определить по команде
docker images
, тогда его тоже надо указать, например:docker run -it --rm -u `id -u`:`id -g` -v "$PWD":/sources -w /sources hub.omp.ru/public/sdk-build-tools:5.0.0
В Windows всё то же самое, только вместо
"$PWD"
нужно использовать"%cd%"
и вместо командid
явные числовые UID пользователя и GID группы:docker run -it --rm -u <UID>:<GID> -v "%cd%":/sources -w /sources hub.omp.ru/public/sdk-build-tools:5.0.0
Опция
--rm
не обязательная, но рекомендуемая, чтобы не занимать дисковое пространство и список контейнеров.Опция
-u 'id -u':'id -g'
рекомендуется, чтобы процессы сборки внутри Docker-контейнера запускались с правами текущего пользователя. В противном случае, они будут запускаться от root, из-за чего возможно появление в хостовой директории новых/изменённых файлов/директорий (например,ts
-файлы переводов), владельцем которых будет root, а обычный пользователь не сможет их изменить или даже удалить.Однако можно добавлять или заменять существующие файлы в контейнере с помощью монтирования, поэтому для удобства предлагается такая команда:
docker run -it --rm -h `hostname` -u `id -u`:`id -g` -e HOME=/tmp -v "$PWD":/sources -v <путь>/.bashrc:/tmp/.bashrc -v <путь>/.bash_history:/tmp/.bash_history -w /sources hub.omp.ru/public/sdk-build-tools:5.0.0
В Windows:
docker run -it --rm -h `hostname` -u <UID>:<GID> -e HOME=/tmp -v "%cd%":/sources -v <путь>/.bashrc:/tmp/.bashrc -v <путь>/.bash_history:/tmp/.bash_history -w /sources hub.omp.ru/public/sdk-build-tools:5.0.0
Опция
-e HOME=/tmp
служит для переопределения переменной окружения$HOME
в Docker-контейнере. В случае, если процессы в контейнере запускаются не от имени root, а от обычного пользователя (опция-u
), то$HOME
определяется в/
, что для этого пользователя является директорией только для чтения. Неизвестно, для каких подпрограмм это может стать проблемой в случае более или менее нетривиальной сборки, поэтому рекомендуется на всякий случай добавлять опцию-e HOME=/tmp
. Дополнительные опции — для украшенияhostname
, оболочкиbash
и запоминанияbash_history
.Если локально есть более свежая версия
apptool
, можно добавить и её:-v <путь>/apptool:/usr/bin/apptool
-
Простейшая команда в Docker-контейнере для кросс-сборки rpm-пакетов под все поддерживаемые архитектуры: ARM32 (armv7hl), ARM64 (AArch64), x64 (x86_64):
apptool build
-
В случае успешной сборки собранные, подписанные и проверенные пакеты будут в директории
/sources/RPMS
в контейнере, отображающейся с соответствующей директории с хоста.
Если вариант по умолчанию не устраивает, можно использовать команды и дополнительные опции apptool
:
-
Например, указать сборку только под заданные архитектуры, отключить подпись и/или валидацию собранных пакетов; а потом сделать это вручную отдельными командами:
apptool build --arm32 --x64 --nosign --noval apptool sign -k <путь>/system-developer-key.pem -c <путь>/system-developer-cert.pem RPMS/* apptool validate -p regular --color auto RPMS/*
-
Если
.spec
-файл приложения лежит по нестандартному пути, либо их несколько (например, один.spec
-файл дляmb2
, а другой дляapptool
), то указать, какой именно выбрать, можно командой:apptool -s <путь/файл.spec>
Поддерживаются как абсолютные, так и относительные пути.
-
Можно включить режим явной теневой сборки: указать директорию исходных текстов с помощью опции
--srcdir
или/и целевую директорию сборки с помощью опции--dstdir
, но в этом случае отключается режим сборки нескольких архитектур подряд, поэтому необходимо указать целевую архитектуру явно, и притом только одну, например:apptool build --x64 --dstdir builddir
Или, подразумевая, что сборка происходит в текущей директории:
mkdir builddir && cd builddir apptool build --arm32 --srcdir ..
или
apptool build --arm64 --srcdir /sources
Существует возможность комбинировать опции
--srcdir
и--dstdir
. -
Также можно выполнить только этап конфигурирования (шаги
%qmake5
или%cmake
):apptool build --configure
возможно выполнение с какими-либо ещё опциями, например, выбранной архитектурой и
--srcdir
/--dstdir
. -
Можно передать дополнительные опции для сборки, например, для включения отладочной информации (для Debug-конфигурации) передать
qmake
опции:apptool build -d --extra-options CONFIG+=debug CONFIG+=qml_debug
или
apptool build -d --extra-options "CONFIG+=debug CONFIG+=qml_debug"
А для проекта на
cmake
— другим способом:apptool build -d --extra-options " -DCMAKE_BUILD_TYPE:STRING=Debug"
Здесь приходится использовать кавычки и лидирующий пробел, чтобы опция для
cmake
не рассматривалась как опция дляapptool
. -
Чтобы каждый раз не указывать собственные ключ и сертификат и выполнять этап подписи автоматически, как обычно, а не вручную, можно "сохранить" эти значения, указав их в конфигурации:
apptool config --sign-key <путь>/developer-extended-key.pem --sign-cert <путь>/developer-extended-cert.pem
Тогда подпись будет автоматически выполняться с использованием этих значений.
Обязательно надо задать и ключ, и соответствующий сертификат, иначе по-прежнему будет использоваться дефолтная пара ключ-сертификат, определяемая по профилю безопасности.
<путь>
может быть относительным, если ключи лежат в каталоге с приложением, или абсолютным; но если используются не стандартные ключи, поставляемые с Docker-образом, а пользовательские, то каталог с ними надо монтировать в Docker-контейнер отдельной опцией. -
Наконец, можно для текущего проекта изменить профиль безопасности по умолчанию:
apptool config --validate-profile extended
-
Команды
apptool sign
иapptool validate
, соответственно, подписывающие и валидирующие собранные пакеты, по умолчанию не принимают опций и используют настройки по умолчанию, либо заданные с помощью командыapptool config
.Но если всё-таки подать им какие-либо параметры, они используют их вместо настроек по умолчанию и передадут напрямую утилитам, соответственно,
rpmsign-external sign
иrpm-validator
, однако в этом случае это равносильно тому, чтобы вызвать их напрямую с этими же параметрами. -
Подробнее про параметры apptool см. в справке по использованию:
apptool -h
,apptool build -h
и т.д.
Особенности apptool
Текущая версия apptool
использует неявную теневую сборку ("shadow build"), по умолчанию скрытую от пользователя,
т.е. она выполняет сборку в поддиректориях .apptool/arm32
, .apptool/arm64
, .apptool/x64
относительно корневого каталога проекта.
При последующих сборках эти каталоги используются в качестве кэша для инкрементальной сборки.
Если необходимо пересобрать пакеты заново с нуля, можно удалить каталог .apptool
или его подкаталоги для соответствующих архитектур, с помощью команды apptool clean
или вручную.
Однако можно задать свою директорию для теневой сборки в явном виде с помощью опции --dstdir
и директорию с исходниками с помощью опции --srcdir
, но в этом случае сборка будет только для одной архитектуры,
которую необходимо явно выбрать с помощью соответствующей опции.
Возможен вариант с указанием только директории исходных текстов, тогда сборка происходит в текущей директории.
apptool
поддерживает только системы сборки qmake
и cmake и не поддерживает GNU Autotools и другие.
Более того, все вызовы qmake
и cmake
должны быть в виде макросов %qmake5
и %cmake
в .spec
-файле проекта,
потому что именно они поддерживают возможность кросс-сборки с помощью скрытых опций, непрозрачных для пользователя.
Поэтому, если в подпроектах вызывается, например, cmake
для сборки библиотек, их надо переписать таким образом,
чтобы перенести вызовы cmake
из проектных файлов в .spec
-файл в виде макросов %cmake
.
Возможно, придётся собирать сначала все подпроекты, а только после них сам корневой проект.
Известные проблемы и ограничения apptool
При использовании инструмента apptool
возникают
определенные проблемы и ограничения, о которых важно знать:
-
Текущая версия
apptool
заточена под использование только систем сборки qmake или cmake.Системы сборки GNU Autotools, Meson и другие — не поддерживаются.
В
.spec
-файле проекта в секции%build
может быть только вызов макроса%qmake5
или/и%cmake
, затем%make_build
, а в секции%install
— макрос%make_install
.Если же вызывается что-либо другое (
meson
,./configure
,./bootstrap
и т.д., голые вызовыqmake
илиcmake
) в.spec
-файле или где-либо ещё, например, во вложенных подпроектах, то кросс-компиляция (сборка ненативных архитектур armv7hl и aarch64) работать не будет. -
Не поддерживаются вызовы
cmake
изqmake
-подпроектов.Если во вложенных подпроектах (например, библиотеках) вызывается
cmake
, то эти вызовы необходимо переносить в.spec
-файл и переписать с использованием макросов%cmake
. И собирать сначала подпроекты, а потом сам корневой проект. -
Не поддерживается эмуляция ненативных архитектур (armv7hl и aarch64) в каком-либо виде до, во время или после сборки проекта.
Поскольку
apptool
не используетsb2
/mb2
иqemu
, а в Docker-образе соответствующих утилит вообще нет, то различного рода pre-configure тесты, запускаемые на исполнение системами GNU Autotools и cmake для определения свойств системы, не будут работать правильно, поэтому их не должно быть, либо они не должны быть обязательными. (Однако это не относится к compile-only тестам, проверяющим параметры системы на этапе компиляции.) -
По той же причине не поддерживается тестирование rpm-пакетов после сборки (секция
%check
). -
В Docker-контейнере не поддерживается запуск 32-битных динамически слинкованных x86-программ (i386-i686). Но статически слинкованных — поддерживается.
Соответственно, недоступна сборка пакетов под архитектуру i486.
-
По умолчанию, в случае Out-Of-Source отладочных сборок (с опцией
-d
) некорректно генерируютсяdebugsource
-пакеты (либо пустые, либо полупустые, содержащие толькоmoc
-сгенерированные исходники). -
Текущая версия
apptool
не откатывает сделанные в репозитории локальные изменения после сборки.Поэтому для успешной последовательной сборки нескольких архитектур подряд, ответственностью разработчика приложений является необходимость убедиться, что команды из секций
%build
и%install
не изменяют исходные файлы в дереве проекта. -
SDKBuildTools
поставляется в виде stateless-docker-образа, т.е. изменения, сделанные локально в Docker-контейнере, не сохраняются после перезапуска.Чтобы сохранить свои изменения на постоянной основе, можно либо монтировать отдельные файлы/директории из хоста в контейнер с помощью опции
docker -v
, либо создать свой слой образа с помощью командыdocker container commit
, либо создать свой образ на базе существующего с помощью написанияDockerfile
. -
Макрос
%{_sourcedir}
в.spec
-файле может разворачиваться как в абсолютный, так и в относительный путь до директорииrpm
в зависимости от ряда условий. Это стоит учитывать, чтобы не столкнуться с ошибкой доступа при нахождении не в корне проекта (например, в случаеmkdir build && cd build
).