Сборка с помощью flatpak-builder#
flatpak-builder — основной инструмент декларативной сборки приложений из исходного
кода. Разработчик описывает структуру приложения в манифесте (JSON или YAML), а
flatpak-builder выполняет все шаги: загружает исходный код, компилирует, размещает
результат в правильной структуре каталогов и экспортирует в репозиторий.
Примечание
flatpak-builder предназначен для сборки приложений из исходного кода.
Для конвертации готовых deb-пакетов в формат Flatpak используется
инструмент aft-app, описанный в разделе aft-app: сборка приложений из deb-пакетов.
Формат манифеста#
Манифест описывает приложение: его идентификатор, рантайм, процесс сборки и необходимые разрешения. Поддерживаются форматы JSON и YAML.
Обязательные поля#
app-idИдентификатор приложения в формате обратного DNS.
runtimeИдентификатор рантайма, на котором будет работать приложение.
runtime-versionВерсия (ветка) рантайма.
sdkИдентификатор SDK, используемого для сборки.
commandКоманда запуска приложения (имя исполняемого файла в
/app/bin/).modulesСписок модулей — компонентов, из которых собирается приложение.
Пример минимального манифеста в формате JSON:
{
"app-id": "org.example.MyApp",
"runtime": "org.example.Platform",
"runtime-version": "stable",
"sdk": "org.example.Sdk",
"command": "myapp",
"modules": [
{
"name": "myapp",
"buildsystem": "cmake-ninja",
"sources": [
{
"type": "archive",
"url": "https://example.com/myapp-1.0.tar.xz",
"sha256": "abc123..."
}
]
}
]
}
Тот же манифест в формате YAML:
app-id: org.example.MyApp
runtime: org.example.Platform
runtime-version: stable
sdk: org.example.Sdk
command: myapp
modules:
- name: myapp
buildsystem: cmake-ninja
sources:
- type: archive
url: https://example.com/myapp-1.0.tar.xz
sha256: abc123...
Необязательные поля верхнего уровня#
finish-argsМассив строк, определяющих разрешения песочницы. Каждая строка задаёт одно разрешение в формате
--<тип>=<значение>:"finish-args": [ "--share=network", "--share=ipc", "--socket=x11", "--socket=wayland", "--socket=pulseaudio", "--device=dri", "--filesystem=xdg-download:ro", "--talk-name=org.freedesktop.Notifications" ]
build-optionsГлобальные параметры сборки, применяемые ко всем модулям:
"build-options": { "cflags": "-O2 -g", "cxxflags": "-O2 -g", "env": { "V": "1" }, "strip": true, "no-debuginfo": false }
Ключевые параметры:
cflags/cxxflags/ldflags— флаги компиляции и линковки;env— переменные окружения для сборки;prefix— префикс установки (по умолчанию/app);strip— удалить отладочные символы (по умолчаниюtrue);no-debuginfo— не создавать отдельный пакет с отладочной информацией;append-path/prepend-path— дополнитьPATH;append-ld-library-path/prepend-ld-library-path— дополнитьLD_LIBRARY_PATH;append-pkg-config-path/prepend-pkg-config-path— дополнитьPKG_CONFIG_PATH.
cleanupШаблоны файлов, удаляемых из результата сборки:
"cleanup": [ "/include", "/lib/pkgconfig", "/lib/*.a", "/lib/*.la", "/share/doc", "/share/man" ]
cleanup-commandsКоманды, выполняемые в песочнице после сборки всех модулей для финальной очистки.
copy-iconЕсли
true, копирует иконку приложения из установленных файлов в каталог экспорта.rename-iconПереименовывает иконку приложения (значение — старое имя без расширения).
rename-desktop-fileПереименовывает
.desktop-файл приложения.rename-appdata-fileПереименовывает файл AppStream-метаданных.
desktop-file-name-prefix/desktop-file-name-suffixДобавляет префикс или суффикс к полю
Nameв.desktop-файле (используется для нестабильных сборок, например(Nightly)).sdk-extensionsРасширения SDK, устанавливаемые в сборочную среду (массив строк). Применяется для подключения компиляторов или инструментов, не входящих в базовый SDK:
"sdk-extensions": [ "org.example.Sdk.Extension.rust-stable" ]
inherit-extensionsРасширения рантайма, наследуемые приложением.
add-extensionsОпределение точек расширений для самого приложения.
baseИдентификатор базового приложения, файлы которого включаются в сборку. Используется для общих компонентов, разделяемых между приложениями.
base-versionВерсия базового приложения.
separate-localesЕсли
true(по умолчанию), выделяет файлы локализации в отдельное расширение.
Модули#
Модуль — единица сборки, соответствующая одному компоненту (библиотеке или приложению). Модули собираются последовательно, и каждый последующий модуль может использовать результаты сборки предыдущих.
Структура модуля#
{
"name": "имя-модуля",
"buildsystem": "cmake-ninja",
"config-opts": ["--опция=значение"],
"builddir": true,
"sources": []
}
Обязательные поля модуля:
name— уникальное имя модуля;sources— массив источников (откуда брать исходный код).
Системы сборки (buildsystem)#
flatpak-builder поддерживает следующие системы сборки:
- autotools (по умолчанию)
Классическая система:
configure && make && make install. Параметры передаются черезconfig-opts.{ "name": "libfoo", "buildsystem": "autotools", "config-opts": ["--disable-static", "--enable-shared"] }
- cmake-ninja
CMake с генератором Ninja.
flatpak-builderвызываетcmake -G Ninjaс последующимninja install. Требуетbuilddir: true.{ "name": "myapp", "buildsystem": "cmake-ninja", "builddir": true, "config-opts": ["-DCMAKE_BUILD_TYPE=Release"] }
- cmake
CMake с генератором Makefile (
cmake && make && make install).- meson
Meson с Ninja:
meson setup && ninja install. Требуетbuilddir: true.{ "name": "mylib", "buildsystem": "meson", "builddir": true, "config-opts": ["-Dtests=false"] }
- simple
Ручная сборка. Команды указываются в поле
build-commands:{ "name": "myapp", "buildsystem": "simple", "build-commands": [ "make PREFIX=/app", "make PREFIX=/app install" ] }
- qmake
Qt-система сборки:
qmake && make && make install.{ "name": "qt-app", "buildsystem": "qmake", "config-opts": ["CONFIG+=release"] }
Дополнительные параметры модуля#
config-optsМассив строк — параметры, передаваемые системе сборки при конфигурации.
make-argsМассив строк — параметры, передаваемые
make(или аналогу).make-install-argsМассив строк — параметры, передаваемые
make install.build-commandsМассив команд для системы сборки
simple.post-installМассив команд, выполняемых после установки модуля.
builddirЕсли
true, сборка выполняется в отдельном каталоге (out-of-tree build). Обязательно дляcmake-ninjaиmeson.subdirПодкаталог внутри исходного дерева, в котором запускается сборка.
no-autogenЕсли
true, пропускает автоматический запускautoreconf/autogen.sh.no-parallel-makeЕсли
true, отключает параллельную сборку (-j1).no-make-installЕсли
true, пропускает фазуmake install.disabledЕсли
true, модуль полностью пропускается.only-arches/skip-archesМассивы архитектур, для которых модуль собирается или пропускается.
cleanupДополнительные шаблоны очистки, специфичные для данного модуля.
build-optionsПараметры сборки, переопределяющие глобальные для данного модуля.
modulesВложенные модули — зависимости, которые необходимо собрать перед текущим модулем.
Типы источников (sources)#
Каждый модуль содержит массив источников, определяющих, откуда загружается исходный код. Источники обрабатываются последовательно: файлы второго источника накладываются поверх файлов первого.
archive#
Загрузка и распаковка архива (tar.gz, tar.xz, tar.bz2, zip):
{
"type": "archive",
"url": "https://example.com/myapp-1.0.tar.xz",
"sha256": "abc123def456...",
"strip-components": 1
}
Ключевые поля:
url— URL архива;sha256— контрольная сумма SHA-256 (обязательно);md5/sha1/sha512— альтернативные контрольные суммы;strip-components— количество удаляемых начальных компонентов пути (аналогtar --strip-components);dest— подкаталог для распаковки;dest-filename— имя файла при сохранении.
git#
Клонирование Git-репозитория:
{
"type": "git",
"url": "https://github.com/example/myapp.git",
"tag": "v1.0",
"commit": "abc123def456..."
}
Ключевые поля:
url— URL Git-репозитория;branch— ветка для клонирования;tag— тег;commit— хеш коммита (рекомендуется для воспроизводимости);disable-submodules— не инициализировать подмодули;disable-shallow-clone— полное клонирование вместо shallow.
file#
Загрузка одного файла:
{
"type": "file",
"url": "https://example.com/config.ini",
"sha256": "abc123...",
"dest-filename": "default.ini"
}
dir#
Копирование локального каталога:
{
"type": "dir",
"path": "/путь/к/каталогу"
}
script#
Генерация скрипта из массива команд:
{
"type": "script",
"commands": [
"#!/bin/bash",
"exec /app/lib/myapp/start.sh \"$@\""
],
"dest-filename": "myapp-wrapper.sh"
}
shell#
Выполнение команд в исходном каталоге (применяется до начала сборки):
{
"type": "shell",
"commands": [
"sed -i 's/old/new/g' Makefile",
"autoreconf -fiv"
]
}
patch#
Применение патча:
{
"type": "patch",
"path": "fix-build.patch",
"strip-components": 1
}
extra-data#
Данные, загружаемые при установке (не при сборке). Используется для проприетарного ПО, которое не может распространяться в репозитории:
{
"type": "extra-data",
"filename": "proprietary.tar.gz",
"url": "https://vendor.example.com/download/app.tar.gz",
"sha256": "abc123...",
"size": 52428800
}
Процесс сборки#
Рассмотрим полный процесс сборки приложения с помощью flatpak-builder.
Сборка и экспорт в репозиторий#
Базовая команда сборки:
flatpak-builder --repo=repo --force-clean build-dir org.example.MyApp.json
Параметры:
build-dir— каталог, в котором будет создана промежуточная сборочная структура (при повторной сборке каталог пересоздаётся при указании--force-clean);--repo=repo— путь к OSTree-репозиторию, куда экспортируется результат;org.example.MyApp.json— путь к манифесту.
Сборка без экспорта#
Для отладки удобно собрать приложение без экспорта в репозиторий:
flatpak-builder --force-clean build-dir org.example.MyApp.json
Результат доступен в каталоге build-dir/. Для запуска:
flatpak-builder --run build-dir org.example.MyApp.json myapp
Команда --run запускает указанный исполняемый файл внутри сборочной среды
с применением разрешений из finish-args.
Основные параметры flatpak-builder#
--repo=<путь>Экспортировать результат в OSTree-репозиторий по указанному пути. Репозиторий создаётся автоматически, если не существует.
--force-cleanУдалить существующий сборочный каталог перед началом сборки.
--installУстановить приложение в пользовательское пространство после сборки.
--install-deps-from=<имя-репозитория>Автоматически установить отсутствующие зависимости (рантайм, SDK, расширения) из указанного репозитория.
--userВыполнять операции в пользовательском пространстве (без прав суперпользователя).
--disable-cacheОтключить кеширование промежуточных результатов.
--ccacheИспользовать
ccacheдля ускорения повторных сборок.--keep-build-dirsНе удалять каталоги отдельных модулей после сборки (для отладки).
--sandboxВыполнять сборку в изолированной песочнице (требует установленных рантаймов).
--disable-downloadНе загружать источники (использовать только локальный кеш).
--download-onlyТолько загрузить источники, не начинать сборку.
--stop-at=<модуль>Остановить сборку перед указанным модулем. Полезно для интерактивной отладки — после остановки можно войти в среду сборки через
--run.--gpg-sign=<идентификатор-ключа>Подписать экспортированный коммит указанным GPG-ключом.
--gpg-homedir=<путь>Каталог с GPG-ключами.
--default-branch=<ветка>Использовать указанную ветку вместо значения из манифеста.
--arch=<архитектура>Собрать для указанной архитектуры (по умолчанию — архитектура хоста).
--subject=<текст>Описание коммита в репозитории (одна строка).
--body=<текст>Расширенное описание коммита.
Инкрементальная сборка и кеширование#
flatpak-builder автоматически кеширует результаты сборки каждого модуля.
При повторной сборке пересобираются только модули, источники которых изменились.
Кеш хранится в каталоге .flatpak-builder/ рядом с манифестом:
.flatpak-builder/
├── cache/ # OSTree-репозиторий с кешем модулей
├── checksums/ # Контрольные суммы источников
├── downloads/ # Загруженные архивы и файлы
└── git/ # Клонированные Git-репозитории
Для полной пересборки без кеша:
flatpak-builder --force-clean --disable-cache build-dir org.example.MyApp.json
Для очистки кеша:
rm -rf .flatpak-builder/
Сборка для тестирования#
При разработке удобно собирать и устанавливать приложение одной командой:
flatpak-builder --user --install --force-clean build-dir org.example.MyApp.json
Приложение устанавливается в пользовательское пространство и становится доступно для запуска:
flatpak run org.example.MyApp
Для запуска конкретной команды внутри среды приложения:
flatpak run --command=bash org.example.MyApp
Эта команда откроет оболочку внутри песочницы приложения, что позволяет проверить структуру каталогов, переменные окружения и доступные библиотеки.
Отладка сборки#
Остановка на определённом модуле#
Если сборка модуля завершается ошибкой, удобно остановить процесс перед проблемным модулем и войти в среду сборки:
flatpak-builder --force-clean --stop-at=проблемный-модуль build-dir org.example.MyApp.json
flatpak-builder --run build-dir org.example.MyApp.json bash
Внутри среды сборки доступен рантайм (/usr), результаты сборки предыдущих
модулей (/app) и исходный код текущего модуля.
Сохранение сборочных каталогов#
Для анализа промежуточных результатов:
flatpak-builder --keep-build-dirs --force-clean build-dir org.example.MyApp.json
Каталоги отдельных модулей сохраняются в .flatpak-builder/build/<модуль>/.
Обновление репозитория#
После экспорта приложения в репозиторий, для корректной работы с клиентами необходимо обновить метаданные:
flatpak build-update-repo repo
При использовании flatpak-builder --repo метаданные обновляются автоматически.
Для генерации статических дельт (ускорение загрузки обновлений):
flatpak build-update-repo --generate-static-deltas repo
Для очистки устаревших объектов:
flatpak build-update-repo --prune repo
Подпись репозитория#
Для обеспечения целостности и подлинности пакетов репозиторий может быть подписан
GPG-ключом. Подпись накладывается как на отдельные коммиты (при экспорте),
так и на файл summary (при обновлении репозитория).
Подпись при сборке:
flatpak-builder --repo=repo --gpg-sign=<ID-ключа> --force-clean build-dir org.example.MyApp.json
Подпись summary:
flatpak build-update-repo --gpg-sign=<ID-ключа> repo
Полный пример: сборка GTK-приложения#
Рассмотрим сборку приложения, использующего GTK и систему сборки Meson.
Манифест org.example.TextEditor.json:
{
"app-id": "org.example.TextEditor",
"runtime": "org.example.Platform",
"runtime-version": "stable",
"sdk": "org.example.Sdk",
"command": "texteditor",
"finish-args": [
"--share=ipc",
"--socket=fallback-x11",
"--socket=wayland",
"--device=dri",
"--filesystem=home"
],
"cleanup": [
"/include",
"/lib/pkgconfig",
"/lib/*.a",
"/lib/*.la",
"/share/doc",
"/share/man"
],
"modules": [
{
"name": "texteditor",
"buildsystem": "meson",
"builddir": true,
"config-opts": ["-Dtests=false"],
"sources": [
{
"type": "archive",
"url": "https://example.com/texteditor-2.0.tar.xz",
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
]
}
]
}
Сборка и установка:
flatpak-builder --user --install --force-clean build-dir org.example.TextEditor.json
Запуск:
flatpak run org.example.TextEditor
Полный пример: сборка Qt-приложения с зависимостями#
Рассмотрим приложение, которому требуется библиотека, отсутствующая в рантайме.
Манифест org.example.ImageViewer.yaml:
app-id: org.example.ImageViewer
runtime: org.example.Platform
runtime-version: stable
sdk: org.example.Sdk
command: imageviewer
finish-args:
- --share=ipc
- --socket=x11
- --socket=wayland
- --device=dri
- --filesystem=xdg-pictures:ro
cleanup:
- /include
- /lib/pkgconfig
- /lib/*.a
- /lib/*.la
modules:
- name: libexif
buildsystem: autotools
config-opts:
- --disable-static
sources:
- type: archive
url: https://example.com/libexif-0.6.24.tar.xz
sha256: abc123...
- name: imageviewer
buildsystem: qmake
sources:
- type: archive
url: https://example.com/imageviewer-3.1.tar.xz
sha256: def456...
В этом примере модуль libexif собирается первым. Его заголовочные файлы
и библиотеки доступны при сборке модуля imageviewer.
Сборка:
flatpak-builder --repo=repo --force-clean build-dir org.example.ImageViewer.yaml
Интеграция с CI/CD#
flatpak-builder легко интегрируется в системы непрерывной сборки.
Рассмотрим пример для GitLab CI:
flatpak-build:
stage: build
script:
- flatpak-builder --repo=repo --force-clean
--gpg-sign=${GPG_KEY_ID}
--disable-cache
build-dir org.example.MyApp.json
- flatpak build-update-repo
--generate-static-deltas
--gpg-sign=${GPG_KEY_ID}
repo
artifacts:
paths:
- repo/
Важно
В среде CI рекомендуется использовать --disable-cache для гарантии
воспроизводимости сборки и --gpg-sign для подписи результата.