Сборка с помощью 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 для подписи результата.