Ручная сборка командами flatpak build#

Помимо flatpak-builder, Flatpak предоставляет низкоуровневые команды семейства flatpak build, позволяющие контролировать каждый этап сборки. Эти команды лежат в основе работы flatpak-builder и применяются напрямую, когда декларативный подход недостаточен:

  • нестандартный процесс сборки, не укладывающийся в модель flatpak-builder;

  • упаковка предварительно скомпилированного ПО без пересборки;

  • интеграция в существующие системы сборки (Makefile, скрипты);

  • создание рантаймов и SDK;

  • глубокая отладка сборки.

Обзор конвейера#

Ручная сборка состоит из четырёх основных этапов:

  1. flatpak build-init - создание сборочного каталога с метаданными.

  2. flatpak build - выполнение команд сборки в песочнице.

  3. flatpak build-finish - финализация: назначение разрешений и экспорт файлов интеграции с рабочим столом.

  4. flatpak build-export - помещение результата в OSTree-репозиторий.

Дополнительно: flatpak build-bundle создаёт автономный бандл из репозитория, flatpak build-update-repo обновляет метаданные репозитория.

flatpak build-init#

Команда создаёт и инициализирует сборочный каталог, формируя базовую структуру файловой системы и файл метаданных.

Синтаксис:

flatpak build-init [ПАРАМЕТРЫ] КАТАЛОГ ИДЕНТИФИКАТОР SDK РАНТАЙМ [ВЕТКА]

Позиционные аргументы: путь к создаваемому каталогу, идентификатор приложения, ссылка на SDK, ссылка на рантайм и необязательная ветка приложения.

Основные параметры:

  • --arch=<архитектура> - архитектура сборки (по умолчанию архитектура хоста).

  • --type=<тип> - тип пакета: app (по умолчанию), runtime или extension.

  • --var=<рантайм> - инициализировать каталог var/ содержимым из рантайма.

  • --writable-sdk (-w) - скопировать SDK в каталог usr/ с правами записи (нужно при сборке рантаймов).

  • --base=<приложение> и --base-version=<версия> - инициализировать files/ содержимым базового приложения.

  • --sdk-extension=<расширение> - подключить расширение SDK в /usr (повторяемо).

  • --tag=<тег> - добавить тег в метаданные (повторяемо).

  • --extension=<имя>=<переменная>[=<значение>] - определить точку расширения.

  • --update - обновить SDK и var/ в существующем каталоге без пересоздания.

Команда создаёт каталог с файлом metadata, пустым каталогом files/ и каталогом var/. Пример файла metadata:

[Application]
name=org.example.MyApp
runtime=org.example.Platform/x86_64/stable
sdk=org.example.Sdk/x86_64/stable

Инициализация каталога для приложения:

flatpak build-init build-dir org.example.MyApp org.example.Sdk org.example.Platform stable

Инициализация для рантайма с записываемым SDK:

flatpak build-init --type=runtime --writable-sdk build-runtime org.example.CustomRuntime org.example.Sdk org.example.Platform stable

flatpak build#

Команда выполняет произвольные команды внутри сборочной песочницы. Файловая система песочницы монтируется из SDK (/usr), сборочного каталога (/app для приложений) и, при необходимости, дополнительных привязок.

Синтаксис:

flatpak build [ПАРАМЕТРЫ] КАТАЛОГ [КОМАНДА [АРГУМЕНТЫ...]]

Если команда не указана, запускается /bin/sh.

Основные параметры:

  • --runtime (-r) - монтировать рантайм вместо SDK (полезно для тестирования; по умолчанию монтируется SDK для компиляции).

  • --readonly - смонтировать файлы приложения только для чтения.

  • --bind-mount=НАЗНАЧЕНИЕ=ИСТОЧНИК - дополнительное монтирование (повторяемо).

  • --build-dir=<каталог> - рабочий каталог внутри песочницы.

  • --with-appdir - смонтировать каталог данных приложения как домашний.

  • --die-with-parent (-p) - завершать процессы в песочнице вместе с родительским.

  • --log-session-bus и --log-system-bus - логировать вызовы к шинам D-Bus.

Внутри песочницы автоматически устанавливаются переменные FLATPAK_ID (идентификатор приложения), FLATPAK_ARCH (архитектура) и FLATPAK_DEST (каталог установки: /app для приложений, /usr для рантаймов).

Компиляция и установка с разными системами сборки. Autotools:

flatpak build build-dir ./configure --prefix=/app
flatpak build build-dir make -j$(nproc)
flatpak build build-dir make install

CMake:

flatpak build build-dir cmake -B _build -G Ninja -DCMAKE_INSTALL_PREFIX=/app -DCMAKE_BUILD_TYPE=Release
flatpak build build-dir ninja -C _build
flatpak build build-dir ninja -C _build install

Meson:

flatpak build build-dir meson setup _build --prefix=/app
flatpak build build-dir ninja -C _build
flatpak build build-dir ninja -C _build install

Если приложение уже скомпилировано, файлы можно разместить напрямую:

flatpak build build-dir cp -r /путь/к/файлам/. /app/
flatpak build build-dir chmod +x /app/bin/myapp

flatpak build-finish#

Команда финализирует сборку: задаёт команду запуска, назначает разрешения песочницы и экспортирует файлы интеграции с рабочим столом (desktop-файлы, иконки, данные AppStream) из files/share/ в export/share/.

Синтаксис:

flatpak build-finish [ПАРАМЕТРЫ] КАТАЛОГ

Параметры команды и метаданных:

  • --command=<команда> - команда запуска. Если не указана, определяется единственный исполняемый файл в files/bin/.

  • --require-version=<версия> - минимальная версия Flatpak для запуска.

  • --no-exports - не копировать файлы из files/share/ в export/share/.

  • --sdk=<sdk> и --runtime=<рантайм> - изменить SDK или рантайм в метаданных.

  • --metadata=<группа>=<ключ>[=<значение>] - задать произвольное значение в метаданных (повторяемо).

  • --no-inherit-permissions - не наследовать разрешения из рантайма.

Разрешения песочницы указываются в том же формате, что и finish-args в манифесте flatpak-builder:

flatpak build-finish build-dir \
    --command=myapp \
    --share=network \
    --share=ipc \
    --socket=x11 \
    --socket=wayland \
    --socket=pulseaudio \
    --device=dri \
    --filesystem=xdg-download:ro \
    --talk-name=org.freedesktop.Notifications \
    --env=LC_ALL=ru_RU.UTF-8

Полный набор параметров разрешений:

  • --share=<ресурс> - network, ipc; --unshare=<ресурс> отзывает разделяемый ресурс.

  • --socket=<сокет> - x11, wayland, fallback-x11, pulseaudio, cups, pcsc, ssh-auth, session-bus, system-bus; --nosocket=<сокет> отзывает доступ.

  • --device=<устройство> - dri, kvm, shm, all; --nodevice=<устройство> отзывает доступ.

  • --filesystem=<путь>[:ro|:rw|:create] - доступ к файловой системе; --nofilesystem=<путь> отзывает доступ.

  • --persist=<каталог> - персистентный каталог в ~/.var/app/<id>/.

  • --env=<переменная>=<значение> и --unset-env=<переменная> - переменные окружения.

  • --own-name=<имя> и --talk-name=<имя> - имена на сессионной шине D-Bus; --system-own-name и --system-talk-name - на системной шине.

  • --allow=<разрешение> - bluetooth, devel.

Точки расширений задаются параметром --extension=<имя>=<переменная>[=<значение>] (переменные directory, version, versions, autodelete, no-autodownload, subdirectories, add-ld-path, merge-dirs); --remove-extension=<имя> удаляет точку, --extension-priority=<значение> задаёт приоритет.

Команда копирует в export/share/ определённые файлы из files/share/:

  • desktop-файлы из каталога applications;

  • иконки всех размеров из каталога icons;

  • данные AppStream из каталогов metainfo и appdata;

  • описания сервисов D-Bus из каталога dbus-1/services;

  • определения MIME-типов из каталога mime/packages;

  • провайдеры поиска GNOME и плагины KRunner.

Имена экспортируемых файлов должны начинаться с идентификатора приложения (org.example.MyApp.desktop, org.example.MyApp.metainfo.xml). Файлы с иными именами пропускаются.

flatpak build-export#

Команда помещает финализированный сборочный каталог в OSTree-репозиторий в виде коммита.

Синтаксис:

flatpak build-export [ПАРАМЕТРЫ] РЕПОЗИТОРИЙ КАТАЛОГ [ВЕТКА]

Позиционные аргументы: путь к репозиторию (создаётся при отсутствии), финализированный сборочный каталог и необязательная ветка (по умолчанию master).

Основные параметры:

  • --subject=<текст> (-s) и --body=<текст> (-b) - описание коммита.

  • --arch=<архитектура> - архитектура (по умолчанию из метаданных).

  • --runtime (-r) - экспортировать как рантайм (каталог usr/ вместо files/).

  • --update-appstream - обновить ветку AppStream.

  • --no-update-summary - не обновлять индекс summary.

  • --gpg-sign=<ключ> и --gpg-homedir=<путь> - подпись коммита.

  • --files=<подкаталог> и --metadata=<файл> - альтернативные имена каталога файлов и файла метаданных.

  • --exclude=<шаблон> и --include=<шаблон> - исключить или вернуть файлы по шаблону.

  • --collection-id=<идентификатор> - идентификатор набора репозитория.

  • --end-of-life=<причина> и --end-of-life-rebase=<идентификатор> - пометить приложение как снятое с поддержки.

  • --timestamp=<метка> - временная метка коммита.

Коммит размещается по ссылке app/<идентификатор>/<архитектура>/<ветка> для приложений и runtime/<идентификатор>/<архитектура>/<ветка> для рантаймов.

Экспорт приложения:

flatpak build-export repo build-dir stable

Экспорт рантайма:

flatpak build-export --runtime repo build-dir stable

Экспорт с подписью:

flatpak build-export --gpg-sign=<ключ> repo build-dir stable

flatpak build-bundle#

Команда создаёт автономный файл бандла (.flatpak) из репозитория. Бандл можно передать на другую машину и установить без подключения к репозиторию.

Синтаксис:

flatpak build-bundle [ПАРАМЕТРЫ] РЕПОЗИТОРИЙ ФАЙЛ ИМЯ [ВЕТКА]

Позиционные аргументы: путь к репозиторию, путь к создаваемому файлу, идентификатор приложения или рантайма и необязательная ветка.

Основные параметры:

  • --runtime - экспортировать рантайм, а не приложение.

  • --arch=<архитектура> - архитектура.

  • --repo-url=<url> - URL репозитория, встраиваемый в бандл; клиент сможет получать обновления после установки.

  • --runtime-repo=<url> - URL файла .flatpakrepo для рантайма.

  • --gpg-keys=<файл> - включить GPG-ключ репозитория в бандл (повторяемо).

  • --gpg-sign=<ключ> и --gpg-homedir=<путь> - подпись бандла.

  • --from-commit=<коммит> - создать инкрементальный дельта-бандл.

  • --oci - создать OCI-образ вместо Flatpak-бандла.

Создание бандла:

flatpak build-bundle repo org.example.MyApp.flatpak org.example.MyApp stable

Создание бандла с информацией о репозитории:

flatpak build-bundle \
    --repo-url=https://repo.example.com/flatpak \
    --gpg-keys=repo-key.gpg \
    repo org.example.MyApp.flatpak org.example.MyApp stable

Установка бандла на целевой машине:

flatpak install org.example.MyApp.flatpak

flatpak build-update-repo#

Команда обновляет метаданные репозитория: пересоздаёт индекс summary, обновляет данные AppStream, генерирует статические дельты и удаляет устаревшие объекты.

Синтаксис:

flatpak build-update-repo [ПАРАМЕТРЫ] РЕПОЗИТОРИЙ

Метаданные репозитория:

  • --title=<название> - название (отображается в списке репозиториев).

  • --comment=<описание> - краткое описание.

  • --description=<описание> - полное описание.

  • --homepage=<url> - адрес сайта репозитория.

  • --icon=<url> - адрес иконки репозитория.

  • --redirect-url=<url> - перенаправление клиентов на новый адрес.

  • --default-branch=<ветка> - ветка по умолчанию.

  • --collection-id=<идентификатор> - идентификатор набора (задаётся однократно).

Генерация дельт:

  • --generate-static-deltas - сгенерировать статические дельты.

  • --static-delta-jobs=<число> - число параллельных потоков генерации.

  • --static-delta-ignore-ref=<шаблон> - не генерировать дельты для ссылок по шаблону.

Подпись:

  • --gpg-sign=<ключ> и --gpg-homedir=<путь> - подпись индекса summary.

  • --gpg-import=<файл> - импортировать GPG-ключ в репозиторий.

Очистка:

  • --prune - удалить неиспользуемые объекты.

  • --prune-dry-run - показать, что будет удалено, без удаления.

  • --prune-depth=<глубина> - глубина обхода при очистке.

Обновление метаданных с генерацией дельт, подписью и очисткой:

flatpak build-update-repo \
    --title="Репозиторий приложений" \
    --generate-static-deltas \
    --gpg-sign=<ключ> \
    --prune \
    repo

Полный пример: сборка приложения#

Полный цикл ручной сборки приложения на C с системой сборки CMake.

Убедимся, что целевые рантайм и SDK установлены:

flatpak list --runtime

Создадим сборочный каталог:

flatpak build-init build-dir org.example.MyApp org.example.Sdk org.example.Platform stable

Скопируем исходный код и выполним компиляцию:

cp -r src/. build-dir/files/src/
flatpak build build-dir cmake -B /app/build -S /app/src -DCMAKE_INSTALL_PREFIX=/app -DCMAKE_BUILD_TYPE=Release
flatpak build build-dir cmake --build /app/build --parallel
flatpak build build-dir cmake --install /app/build
flatpak build build-dir rm -rf /app/build /app/src

Назначим команду запуска и разрешения:

flatpak build-finish build-dir \
    --command=myapp \
    --share=ipc \
    --socket=x11 \
    --socket=wayland \
    --device=dri

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

flatpak build-export repo build-dir stable
flatpak build-update-repo repo

Подключим локальный репозиторий и установим приложение:

flatpak remote-add --user --no-gpg-verify test-repo repo
flatpak install --user test-repo org.example.MyApp
flatpak run org.example.MyApp

Полный пример: сборка рантайма#

Создание рантайма из заранее подготовленной файловой системы.

Инициализация:

flatpak build-init --type=runtime --writable-sdk build-runtime org.example.CustomRuntime org.example.Sdk org.example.Platform stable

Наполнение рантайма (копирование файлов в каталог usr/):

flatpak build build-runtime cp -r /путь/к/rootfs/usr/. /usr/

Экспорт:

flatpak build-export --runtime repo build-runtime stable
flatpak build-update-repo repo

Автоматизация с помощью Makefile#

При регулярной сборке процесс удобно автоматизировать:

APP_ID = org.example.MyApp
SDK = org.example.Sdk
RUNTIME = org.example.Platform
BRANCH = stable
BUILD_DIR = build-dir
REPO = repo

.PHONY: all init build finish export clean

all: init build finish export

init:
    rm -rf $(BUILD_DIR)
    flatpak build-init $(BUILD_DIR) $(APP_ID) $(SDK) $(RUNTIME) $(BRANCH)

build:
    flatpak build $(BUILD_DIR) cmake -B /app/build -S /app/src -DCMAKE_INSTALL_PREFIX=/app
    flatpak build $(BUILD_DIR) cmake --build /app/build --parallel
    flatpak build $(BUILD_DIR) cmake --install /app/build
    flatpak build $(BUILD_DIR) rm -rf /app/build

finish:
    flatpak build-finish $(BUILD_DIR) \
        --command=myapp \
        --share=ipc \
        --socket=x11 \
        --socket=wayland \
        --device=dri

export:
    flatpak build-export $(REPO) $(BUILD_DIR) $(BRANCH)
    flatpak build-update-repo $(REPO)

clean:
    rm -rf $(BUILD_DIR)

Сборка выполняется одной командой:

make all