Упаковка программы в приложение#

Сборка приложения начинается с выбора источника. Источник берут по тому, в каком виде пришла программа. Он определяет только то, откуда взять содержимое. Дальше всё идёт одинаково: разрешение зависимостей, правка путей, метаданные и экспорт.

Выбор источника#

  • Программа есть в подключённых репозиториях Astra - источник repository. Пакет и его дерево зависимостей скачиваются из репозитория, версия закрепляется полем version.

  • Есть готовый файл .deb от поставщика - источник local. Зависимости берутся из состава самого пакета, поэтому в репозиториях его быть не обязано.

  • Файл .deb лежит по ссылке - источник url. Пакет скачивается до анализа, дальше обрабатывается как локальный.

  • Поставка приходит архивом без пакета - источник tar. Раскладка по каталогам приложения задаётся правилами layout, недостающие библиотеки докладываются пакетами из репозитория.

  • Программа уже установлена в системе и её нужно перенести - источник system. В сборку попадает сам исполняемый файл, дополнительные файлы по шаблонам и, при включённом includeOwningPackages, пакеты-владельцы целиком.

  • Есть исходники или их нужно собрать - источник sourcedir. Команды сборки выполняются в сборочном окружении, сборочные зависимости объявляются отдельно и в готовое приложение не попадают.

Подбор среды выполнения#

Среда выбирается до сборки командой analyze. Она разбирает зависимости и показывает, какая часть из них уже покрыта средой, а что придётся положить в приложение:

aft-app analyze --package inkscape --runtime org.astra.Gtk --runtime-version 1.8.6

Без флага --runtime среда подбирается сама по покрытию зависимостей. Опрос подключённых репозиториев занимает время, потому что для каждой среды нужно получить её состав ПО; флаг --no-remotes ограничивает поиск уже установленными средами.

Чем выше покрытие, тем меньше приложение и тем меньше в нём дублей. Программе на GTK подходит org.astra.Gtk, программе на Qt5 - org.astra.Qt, на Qt6 - org.astra.Qt6. Консольной программе без графики хватает org.astra.mainPlatform.

Анализ заодно предлагает разрешения песочницы и показывает найденные имена D-Bus, зашитые пути и вызовы хостовых команд. Предложенные разрешения переносятся в манифест не целиком, а по необходимости: лишнее разрешение расширяет доступ приложения к системе.

Программа из репозитория#

Самый частый случай. Достаточно имени пакета и команды запуска:

sudo aft-app package \
    --id ru.example.Inkscape --name Inkscape \
    --runtime org.astra.Gtk --runtime-version 1.8.6 \
    --package inkscape --command inkscape \
    --socket wayland --socket fallback-x11 --device dri \
    --filesystem xdg-documents \
    -o ./repo

Тот же набор в виде манифеста получается командой generate-yaml с теми же флагами. Дальше сборка ведётся через aft-app build, а манифест хранится рядом с остальными файлами проекта.

Готовый пакет от поставщика#

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

version: "1.0"
metadata:
  id: ru.example.Vendor
  name: "Программа поставщика"
  branch: stable
runtime:
  id: org.astra.Qt
  version: "1.8.6"
source:
  type: local
  local:
    path: ./vendor-app_3.2.1_amd64.deb
    additionalPaths:
      - ./vendor-libs_3.2.1_amd64.deb
dependencies:
  additional: [libssl3]
files:
  command: vendor-app
permissions:
  sockets: [wayland, fallback-x11]
  filesystems: [xdg-documents]
export:
  repository: ./repo

Если после установки программа не находит свои файлы, значит пути зашиты в бинарник. Что именно она ищет, покажет analyze, а закрыть это без правки бинарника поможет Совместимость с песочницей (astra-shim).

Программа из архива#

В архиве обычно нет ни зависимостей, ни привычной структуры каталогов. Раскладка задаётся явно, а системные библиотеки докладываются пакетами:

source:
  type: tar
  tar:
    path: ./app-3.2.1-linux-x64.tar.xz
    packages: [libnss3, libsecret-1-0]
    layout:
      - { pattern: "app",     dest: bin }
      - { pattern: "lib/*",   dest: lib }
      - { pattern: "share/*", dest: share }

Для источников tar и system deb-зависимости не разбираются: состав задаёт сам источник. Разрешения, библиотеки и имена D-Bus определяются как обычно, по содержимому.

Сборка из исходников#

Команды сборки выполняются в сборочном окружении, куда попадают только объявленные сборочные зависимости. Префикс установки задаётся /app:

source:
  type: sourcedir
  sourcedir:
    path: ./src
    buildDeps:
      packages: [cmake, g++, libssl-dev]
    buildEnv:
      - "PATH=/app/bin:$PATH"
    buildCommands:
      - cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/app
      - cmake --build build -j
      - cmake --install build

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

Когда подходящей среды нет#

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

standalone:
  enabled: true
  rootfs: /

Среда и SDK при этом создаются автоматически по идентификатору приложения, и секцию runtime можно не заполнять. Сборка получается крупной и обновляется целиком, поэтому standalone имеет смысл как последний вариант. Если недостающего немного и оно нужно нескольким приложениям, лучше собрать своё расширение или свою среду, как описано в блоке Своя среда выполнения или расширение.