Инструмент для кросс-сборки apptool
apptool — это инструмент для кросс-сборки пакетов, независимый от mb2 и sb2.
В отличие от sb2, который имитирует нативную компиляцию для разных архитектур,
apptool использует кросс-компиляцию.
- Инструкция по сборке с apptool
- Особенности apptool
- Дополнительные опции
- Известные проблемы и ограничения 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 run -it --rm -u `id -u`:`id -g` -v "$PWD":/sources -w /sources hub.omp.ru/public/sdk-build-tools:5.0.0Посмотреть полный список версий контейнера можно с помощью команды
docker images. -
в 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. В таком случае обычный пользователь не сможет их изменить или удалить.Чтобы изменять подобные файлы, для контейнера можно применить монтирование:
-
в Linux:
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-контейнере. При запуске процессов от имени непривилегированного пользователя (опция-u) стандартное значениеHOME=/tmpнедоступно для записи. ПеренаправлениеHOMEв/tmpобеспечивает возможность создания конфигурационных файлов и временных данных сессии.Опция
-h `hostname`присваивает контейнеру имя той машины, на которой он запускается.Монтирование
~/.bashrcв/tmp/.bashrcобеспечивает загрузку пользовательского окружения (алиасы, функции, переменные) при старте интерактивной сессии bash в контейнере.Монтирование
~/.bash_historyв/tmp/.bash_historyсохраняет историю команд между сессиями контейнера, записывая её в постоянный файл на хосте, что позволяет сохранять контекст работы при повторных запусках.Если в контейнере необходимо использовать другую версию
apptool, можно использовать данную команду для монтирования локального исполняемого файла поверх одноимённого файла внутри контейнера:-v <путь>/apptool:/usr/bin/apptool -
-
Cобрать rpm-пакеты в Docker-контейнере:
apptool buildПакеты собираются под все поддерживаемые архитектуры: ARM32 (armv7hl), ARM64 (AArch64) и x64 (x86_64).
-
После сборки подписанные и проверенные пакеты будут находиться в контейнере в директории
/sources/RPMS. Данная директория располагается в соответствующей директории хоста.
Особенности 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.
О том, как передать дополнительные опции для cmake и qmake, можно прочитать в разделе
Передать дополнительные опции для сборки.
Дополнительные опции
Ниже описаны дополнительные опции для команд apptool.
Более подробную информацию об опциях apptool можно найти в справке, вызванной при помощи
команд apptool -h, apptool build -h и т.д.
Указать сборку под архитектуру
Указать сборку только под заданные архитектуры, отключить подпись и/или валидацию собранных пакетов, а потом затем выполнить подпись и валидацию отдельными командами:
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/*
Примечание. Команды apptool sign и apptool validate, соответственно,
подписывающие и валидирующие собранные пакеты, могут быть использованы без параметров.
Они используют либо настройки по умолчанию, либо заданные с помощью команды apptool config.
Но если передать этим командам какие-либо параметры, они будут использовать данные опции вместо настроек
по умолчанию.
В таком случае опции будут переданы напрямую утилитам, соответственно, rpmsign-external sign и rpm-validator.
Такое действие равносильно тому, чтобы вызвать утилиты напрямую с этими же параметрами.
Выбрать конкретный .spec-файл
Указать конкретный .spec-файл, если у .spec-файла приложения нестандартный путь
либо .spec-файлов несколько (например, один .spec-файл для mb2, а другой для apptool):
apptool -s <путь/файл.spec>
Поддерживаются как абсолютные, так и относительные пути.
Включить режим явной теневой сборки
Включить режим явной теневой сборки:
указать директорию исходных файлов с помощью опции --srcdir или/и целевую
директорию сборки с помощью опции --dstdir.
Можно использовать обе опции в одной команде.
При явной теневой сборке отключается режим сборки нескольких архитектур подряд,
поэтому необходимо указать целевую архитектуру явно, и притом только одну.
Например, команда для сборки в директории builddir:
apptool build --x64 --dstdir builddir
Cборка в текущей директории:
mkdir builddir && cd builddir
apptool build --arm32 --srcdir ..
Сборка в директории /sources:
apptool build --arm64 --srcdir /sources
Выполнить только этап конфигурирования
Выполнить только этап конфигурирования (шаги %qmake5 или %cmake):
apptool build --configure
Возможно выполнение с дополнительными опциями, описанными в этом разделе. Например, выбранной архитектурой, директорией исходных файлов и целевой директорией.
Передать дополнительные опции для сборки
Например, для включения отладочной информации (для 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
При использовании инструмента apptool возникают
определенные проблемы и ограничения, о которых важно знать:
-
Текущая версия
apptoolпредназначена только для систем сборкиqmakeилиcmake. Системы сборки GNU Autotools, Meson и другие не поддерживаются. -
В
.spec-файле проекта в секции%buildможет быть только вызов макроса%qmake5или/и%cmake, затем%make_build. В секции%install— макроса%make_install.Использование иных инструментов конфигурации и сборки (
meson,./configure,./bootstrapи т.д., прямой вызовqmakeилиcmake) как непосредственно в.spec-файле, так и во вложенных подпроектах, нарушает механизм кросс-компиляции для целевых архитектур. -
Не поддерживаются вызовы
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).