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

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

Типичные сценарии использования ручной сборки:

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

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

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

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

  • Глубокая отладка проблем сборки.

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

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

Рисунок 1
Рисунок 1
  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 РАНТАЙМ [ВЕТКА]

Позиционные аргументы:

  • КАТАЛОГ — путь к создаваемому сборочному каталогу;

  • ИДЕНТИФИКАТОР — идентификатор приложения (org.example.MyApp);

  • SDK — ссылка на SDK (org.example.Sdk или org.example.Sdk/x86_64/stable);

  • РАНТАЙМ — ссылка на рантайм (org.example.Platform или org.example.Platform/x86_64/stable);

  • ВЕТКА (необязательный) — ветка приложения.

Параметры#

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

Архитектура сборки (x86_64, aarch64). По умолчанию — архитектура хоста.

--type=<тип>

Тип собираемого пакета:

  • app (по умолчанию) — приложение;

  • runtime — рантайм;

  • extension — расширение.

--var=<рантайм>

Инициализировать каталог var/ содержимым из указанного рантайма.

--writable-sdk, -w

Скопировать SDK в каталог usr/ с правами записи. Используется при сборке рантаймов или когда необходимо модифицировать файлы SDK.

--base=<приложение>

Инициализировать files/ содержимым указанного базового приложения.

--base-version=<версия>

Версия базового приложения.

--base-extension=<расширение>

Включить указанное расширение базового приложения (можно указывать многократно).

--sdk-extension=<расширение>

Подключить расширение SDK в /usr (можно указывать многократно).

--sdk-dir=<каталог>

Альтернативное имя каталога для SDK (по умолчанию usr).

--tag=<тег>

Добавить тег в метаданные (можно указывать многократно).

--extension=<ИМЯ>=<ПЕРЕМЕННАЯ>[=<ЗНАЧЕНИЕ>]

Определить точку расширения в метаданных.

--update

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

Создаваемая структура#

build-dir/
├── metadata            # INI-файл с метаданными
├── files/              # Каталог для файлов приложения (пустой)
├── var/                # Изменяемые данные
│   ├── tmp/
│   ├── lib/
│   └── run -> /run
└── .gitignore

Файл 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-dir org.example.CustomRuntime org.example.Sdk org.example.Platform stable

flatpak build#

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

Синтаксис#

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

Если КОМАНДА не указана, запускается /bin/sh.

Параметры#

--runtime, -r

Использовать рантайм вместо SDK. По умолчанию flatpak build монтирует SDK (для компиляции). С этим флагом монтируется целевой рантайм, что полезно для тестирования.

--readonly

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

--bind-mount=НАЗНАЧЕНИЕ=ИСТОЧНИК

Дополнительное монтирование внутрь песочницы (можно указывать многократно).

--build-dir=<каталог>

Рабочий каталог внутри песочницы (по умолчанию /).

--sdk-dir=<каталог>

Каталог с SDK (по умолчанию usr).

--metadata=<файл>

Путь к файлу метаданных (по умолчанию metadata в сборочном каталоге).

--with-appdir

Смонтировать каталог данных приложения (~/.var/app/<id>) как домашний каталог.

--die-with-parent, -p

Завершить процессы в песочнице при завершении родительского процесса.

--log-session-bus

Логировать вызовы к сессионной шине D-Bus.

--log-system-bus

Логировать вызовы к системной шине D-Bus.

Переменные окружения в песочнице#

flatpak build автоматически устанавливает следующие переменные:

  • FLATPAK_ID — идентификатор приложения;

  • FLATPAK_ARCH — архитектура (x86_64, aarch64);

  • 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=<команда>

Команда запуска приложения. Если не указана, build-finish пытается определить единственный исполняемый файл в files/bin/.

--require-version=<МАЖОРНАЯ.МИНОРНАЯ.МИКРО>

Минимальная версия Flatpak, необходимая для запуска приложения.

--no-exports

Не копировать файлы из files/share/ в export/share/.

--sdk=<sdk>

Изменить SDK в метаданных.

--runtime=<рантайм>

Изменить рантайм в метаданных.

--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=<имя> — имя на сессионной шине D-Bus (own)

  • --talk-name=<имя> — имя на сессионной шине D-Bus (talk)

  • --system-own-name=<имя> — имя на системной шине D-Bus (own)

  • --system-talk-name=<имя> — имя на системной шине D-Bus (talk)

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

Работа с точками расширений#

--extension=<ИМЯ>=<ПЕРЕМЕННАЯ>[=<ЗНАЧЕНИЕ>]

Определить точку расширения в метаданных. Переменные:

  • directory — каталог монтирования;

  • version / versions — версия расширения;

  • autodelete — автоудаление;

  • no-autodownload — не загружать автоматически;

  • subdirectories — поддержка подкаталогов;

  • add-ld-path — дополнение LD_LIBRARY_PATH;

  • merge-dirs — каталоги для объединения.

--remove-extension=<ИМЯ>

Удалить точку расширения.

--extension-priority=<ЗНАЧЕНИЕ>

Приоритет расширения (только при сборке расширений).

Поведение экспорта#

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

  • applications/*.desktop — файлы рабочего стола;

  • icons/** — иконки всех размеров;

  • metainfo/*.metainfo.xml и appdata/*.appdata.xml — данные AppStream;

  • dbus-1/services/*.service — описания сервисов D-Bus;

  • mime/packages/*.xml — определения MIME-типов;

  • gnome-shell/search-providers/*.ini — провайдеры поиска GNOME;

  • krunner/dbusplugins/*.desktop — плагины KRunner.

Примечание

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

Пример#

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

flatpak build-export#

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

Синтаксис#

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

Позиционные аргументы:

  • РЕПОЗИТОРИЙ — путь к OSTree-репозиторию (создаётся при отсутствии);

  • КАТАЛОГ — финализированный сборочный каталог;

  • ВЕТКА (необязательный) — ветка, в которую помещается коммит (по умолчанию master).

Параметры#

--subject=<текст>, -s

Однострочное описание коммита.

--body=<текст>, -b

Расширенное описание коммита.

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

Архитектура (по умолчанию — из метаданных).

--runtime, -r

Экспортировать как рантайм (каталог usr/ вместо files/).

--update-appstream

Обновить ветку AppStream в репозитории.

--no-update-summary

Не обновлять файл summary.

--gpg-sign=<ID-ключа>

Подписать коммит GPG-ключом (можно указывать многократно для нескольких ключей).

--gpg-homedir=<путь>

Каталог с GPG-ключами.

--files=<подкаталог>

Альтернативное имя каталога с файлами (по умолчанию files).

--metadata=<файл>

Альтернативный файл метаданных (по умолчанию metadata).

--exclude=<шаблон>

Исключить файлы по шаблону (можно указывать многократно).

--include=<шаблон>

Включить ранее исключённые файлы (можно указывать многократно).

--collection-id=<идентификатор>

Задать Collection ID репозитория (защита от подмены).

--subset=<имя>

Добавить коммит в именованное подмножество.

--end-of-life=<причина>

Пометить приложение как снятое с поддержки.

--end-of-life-rebase=<идентификатор>

Пометить как снятое с поддержки с перенаправлением на другое приложение.

--token-type=<значение>

Тип токена для доступа к приложению.

--timestamp=<временная-метка>

Установить временную метку коммита.

--disable-fsync

Отключить fsync() (ускоряет запись, но снижает надёжность при сбоях).

--disable-sandbox

Отключить песочницу при валидации иконок.

Формирование ссылки в репозитории#

Коммит размещается в репозитории по ссылке:

  • Для приложений: app/<идентификатор>/<архитектура>/<ветка>

  • Для рантаймов: runtime/<идентификатор>/<архитектура>/<ветка>

Пример#

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

flatpak build-export repo build-dir stable

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

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

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

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

flatpak build-bundle#

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

Синтаксис#

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

Позиционные аргументы:

  • РЕПОЗИТОРИЙ — путь к OSTree-репозиторию;

  • ФАЙЛ — путь к создаваемому файлу .flatpak;

  • ИМЯ — идентификатор приложения или рантайма;

  • ВЕТКА (необязательный) — ветка (по умолчанию master).

Параметры#

--runtime

Экспортировать рантайм (а не приложение).

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

Архитектура.

--repo-url=<url>

URL репозитория, встраиваемый в бандл. Клиент может подключить этот репозиторий для получения обновлений после установки бандла.

--runtime-repo=<url>

URL файла .flatpakrepo для рантайма. Если рантайм не установлен у клиента, он будет предложен для загрузки.

--gpg-keys=<файл>

Включить GPG-ключ репозитория в бандл (можно указывать многократно).

--gpg-sign=<ID-ключа>

Подписать OCI-образ GPG-ключом.

--gpg-homedir=<путь>

Каталог с GPG-ключами.

--from-commit=<коммит>

Создать дельта-бандл от указанного коммита (инкрементальный бандл).

--oci

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

Содержимое бандла#

Бандл представляет собой бинарный файл, содержащий:

  • Статическую дельту OSTree (сжатые файлы приложения);

  • Метаданные (metadata);

  • AppStream-данные (если доступны);

  • Иконки приложения;

  • URL репозитория и GPG-ключи (если указаны).

Пример#

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

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#

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

Синтаксис#

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

Параметры#

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

--title=<название>

Название репозитория (отображается в списке репозиториев).

--comment=<описание>

Краткое описание (одна строка).

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

Полное описание.

--homepage=<url>

URL сайта репозитория.

--icon=<url>

URL иконки репозитория.

--redirect-url=<url>

Перенаправление клиентов на новый URL (при миграции репозитория).

--default-branch=<ветка>

Ветка по умолчанию.

--collection-id=<идентификатор>

Collection ID (устанавливается однократно, изменить нельзя).

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

--generate-static-deltas

Сгенерировать статические дельты для эффективных обновлений.

--static-delta-jobs=<число>

Количество параллельных потоков генерации (по умолчанию — количество CPU).

--static-delta-ignore-ref=<шаблон>

Не генерировать дельты для ссылок, соответствующих шаблону (можно указывать многократно).

Подпись:

--gpg-sign=<ID-ключа>

Подписать файл summary GPG-ключом (можно указывать многократно).

--gpg-homedir=<путь>

Каталог с GPG-ключами.

--gpg-import=<файл>

Импортировать GPG-ключ в репозиторий.

Очистка:

--prune

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

--prune-dry-run

Показать, какие объекты будут удалены, без реального удаления.

--prune-depth=<глубина>

Глубина обхода при очистке (-1 — без ограничений).

Прочее:

--no-update-summary

Не обновлять файл summary.

--no-update-appstream

Не обновлять ветку AppStream.

--no-summary-index

Не генерировать индекс summary.

--authenticator-name=<имя>

Имя аутентификатора для платных или закрытых репозиториев.

--authenticator-install / --no-authenticator-install

Устанавливать аутентификатор автоматически.

--authenticator-option=<КЛЮЧ>=<ЗНАЧЕНИЕ>

Параметры аутентификатора.

Пример#

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

flatpak build-update-repo \
    --title="Репозиторий приложений" \
    --generate-static-deltas \
    --gpg-sign=<ID-ключа> \
    --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