Сборка с помощью flatpak-builder#

flatpak-builder - основной инструмент декларативной сборки приложений из исходного кода. Разработчик описывает приложение в манифесте (JSON или YAML), а flatpak-builder выполняет все шаги: загружает исходный код, компилирует, раскладывает результат в нужную структуру каталогов и экспортирует в репозиторий.

flatpak-builder предназначен для сборки из исходного кода. Для конвертации готовых deb-пакетов в формат Flatpak используется инструмент aft-app (см. Создание приложений (aft-app)).

Формат манифеста#

Манифест описывает приложение: идентификатор, рантайм, процесс сборки и разрешения. Поддерживаются форматы 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 - массив строк, задающих разрешения песочницы. Каждая строка - одно разрешение в формате --<тип>=<значение>, например --share=network, --socket=wayland, --device=dri, --filesystem=xdg-download:ro, --talk-name=org.freedesktop.Notifications.

  • build-options - глобальные параметры сборки для всех модулей: флаги компиляции и линковки (cflags, cxxflags, ldflags), переменные окружения (env), префикс установки (prefix, по умолчанию /app), удаление отладочных символов (strip, по умолчанию включено), дополнение путей (append-path, prepend-path и аналогичные для библиотек и pkg-config).

  • cleanup - шаблоны файлов, удаляемых из результата сборки (заголовки, статические библиотеки, документация и так далее).

  • cleanup-commands - команды очистки, выполняемые в песочнице после сборки всех модулей.

  • copy-icon - копировать иконку приложения в каталог экспорта.

  • rename-icon - переименовать иконку (значение - старое имя без расширения).

  • rename-desktop-file - переименовать desktop-файл.

  • rename-appdata-file - переименовать файл AppStream.

  • desktop-file-name-prefix и desktop-file-name-suffix - добавить префикс или суффикс к имени в desktop-файле (для нестабильных сборок).

  • sdk-extensions - расширения SDK, устанавливаемые в сборочную среду (например, дополнительные компиляторы).

  • inherit-extensions - расширения рантайма, наследуемые приложением.

  • add-extensions - точки расширений самого приложения.

  • base и base-version - базовое приложение, файлы которого включаются в сборку.

  • separate-locales - выделять файлы локализации в отдельное расширение (по умолчанию включено).

Пример секции cleanup:

"cleanup": [
    "/include",
    "/lib/pkgconfig",
    "/lib/*.a",
    "/lib/*.la",
    "/share/doc",
    "/share/man"
]

Модули#

Модуль - единица сборки, соответствующая одному компоненту (библиотеке или приложению). Модули собираются последовательно, и каждый следующий может использовать результаты предыдущих.

Обязательные поля модуля - name (уникальное имя) и sources (массив источников). Базовая структура модуля:

{
    "name": "имя-модуля",
    "buildsystem": "cmake-ninja",
    "config-opts": ["--опция=значение"],
    "builddir": true,
    "sources": []
}

Системы сборки#

flatpak-builder поддерживает несколько систем сборки (поле buildsystem):

  • autotools (по умолчанию) - configure, make, make install. Параметры передаются через config-opts.

  • cmake-ninja - CMake с генератором Ninja. Требует builddir: true.

  • cmake - CMake с генератором Makefile.

  • meson - Meson с Ninja. Требует builddir: true.

  • simple - ручная сборка; команды задаются в поле build-commands.

  • qmake - сборка Qt: qmake, make, make install.

Пример модуля на Meson:

{
    "name": "mylib",
    "buildsystem": "meson",
    "builddir": true,
    "config-opts": ["-Dtests=false"]
}

Пример модуля с ручной сборкой:

{
    "name": "myapp",
    "buildsystem": "simple",
    "build-commands": [
        "make PREFIX=/app",
        "make PREFIX=/app install"
    ]
}

Дополнительные параметры модуля#

  • config-opts - параметры конфигурации, передаваемые системе сборки.

  • make-args и make-install-args - параметры для make и make install.

  • build-commands - команды для системы сборки simple.

  • post-install - команды, выполняемые после установки модуля.

  • builddir - сборка в отдельном каталоге (обязательно для cmake-ninja и meson).

  • subdir - подкаталог исходного дерева, в котором запускается сборка.

  • no-autogen - пропустить автоматический запуск autoreconf или autogen.

  • no-parallel-make - отключить параллельную сборку.

  • no-make-install - пропустить фазу установки.

  • disabled - полностью пропустить модуль.

  • only-arches и skip-arches - архитектуры, для которых модуль собирается или пропускается.

  • cleanup - дополнительные шаблоны очистки для этого модуля.

  • build-options - параметры сборки, переопределяющие глобальные.

  • modules - вложенные модули, собираемые перед текущим.

Типы источников#

Каждый модуль содержит массив источников, определяющих, откуда брать исходный код. Источники обрабатываются по порядку: файлы следующего накладываются поверх предыдущих.

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 (адрес архива), sha256 (контрольная сумма, обязательна; есть альтернативы md5, sha1, sha512), strip-components (сколько начальных компонентов пути удалить), dest (подкаталог для распаковки), dest-filename (имя файла при сохранении).

git#

Клонирование Git-репозитория:

{
    "type": "git",
    "url": "https://github.com/example/myapp.git",
    "tag": "v1.0",
    "commit": "abc123def456..."
}

Ключевые поля: url, branch, tag, commit (хеш коммита, рекомендуется для воспроизводимости), disable-submodules, disable-shallow-clone.

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": [
        "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 --repo=repo --force-clean build-dir org.example.MyApp.json

Здесь build-dir - каталог промежуточной сборочной структуры (при --force-clean пересоздаётся), --repo=repo - путь к репозиторию для экспорта, последний аргумент - путь к манифесту.

Для отладки приложение можно собрать без экспорта:

flatpak-builder --force-clean build-dir org.example.MyApp.json

Запустить собранное из сборочного каталога:

flatpak-builder --run build-dir org.example.MyApp.json myapp

Команда --run запускает исполняемый файл внутри сборочной среды с разрешениями из finish-args.

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

  • --repo=<путь> - экспортировать результат в репозиторий (создаётся при отсутствии).

  • --force-clean - удалить существующий сборочный каталог перед сборкой.

  • --install - установить приложение в пользовательское пространство после сборки.

  • --install-deps-from=<репозиторий> - установить недостающие зависимости (рантайм, SDK, расширения) из указанного репозитория.

  • --user - выполнять операции в пользовательском пространстве.

  • --disable-cache - отключить кеширование промежуточных результатов.

  • --ccache - использовать ccache для ускорения повторных сборок.

  • --keep-build-dirs - не удалять каталоги модулей после сборки.

  • --sandbox - выполнять сборку в изолированной песочнице.

  • --disable-download - использовать только локальный кеш источников.

  • --download-only - только загрузить источники.

  • --stop-at=<модуль> - остановить сборку перед указанным модулем.

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

  • --default-branch=<ветка> - ветка вместо значения из манифеста.

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

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

Инкрементальная сборка и кеширование#

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

Полная пересборка без кеша:

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) и исходный код текущего модуля. Чтобы сохранить каталоги модулей для анализа, используется --keep-build-dirs.

Обновление и подпись репозитория#

После экспорта в репозиторий метаданные обновляются командой:

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=<ключ> --force-clean build-dir org.example.MyApp.json
flatpak build-update-repo --gpg-sign=<ключ> repo

Подробнее про команды семейства flatpak build - в блоке Ручная сборка командами flatpak build.

Пример: приложение на 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"
    ],
    "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

Пример: приложение с зависимостью#

Когда приложению нужна библиотека, отсутствующая в рантайме, её собирают отдельным модулем перед основным. Манифест 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
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.

Интеграция с 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 для подписи результата.