Сборка Wine-приложений во Flatpak с помощью AFT#
Документ описывает, как упаковать Windows-приложение вместе с Wine в один
Flatpak так, чтобы после flatpak install оно запускалось сразу, без ручной
настройки WINEPREFIX. За основу взят инструмент aft-app из набора
AFT.
Концепция#
У aft-app нет отдельного шага установки .exe. Windows-приложение всегда
вносится в сборку одним из способов:
готовый WINEPREFIX - каталог с уже установленной программой кладётся в приложение как шаблон;
портативные файлы - каталог с
.exeкладётся в приложение, префикс создаётся при первом запуске.
Запуск в обоих случаях делает скрипт-обёртка: при первом старте он
разворачивает префикс в каталог данных приложения и вызывает wine app.exe.
Примечание
WINEPREFIX нельзя скачать готовым. Префиксы не распространяются отдельным
файлом: они содержат абсолютные симлинки (dosdevices, ссылки на хостовые
шрифты и устройства) и привязаны к конкретной версии Wine. Префикс всегда
генерируется командой wineboot, а после переноса перепривязывается
командой wineboot -u.
Ключевые особенности Wine#
При упаковке именно Wine есть три момента, которых нет у обычных приложений.
32-битная поддержка (ia32-libs)#
Для запуска 32-битных Windows-программ Wine нужен пакет ia32-libs
(32-битные библиотеки). При выбранном runtime org.astra.Qt он уже входит в
среду выполнения, поэтому докладывать его в приложение не нужно - он не попадает
в сборку и не увеличивает её размер. 32-битные программы работают без
дополнительной настройки.
Проверить, что ia32-libs покрыт средой, можно через analyze - пакет
будет в числе уже покрытых средой, а не требующих добавления:
$ aft-app analyze --package wine --runtime org.astra.Qt --runtime-version 1.8.5
Примечание
На голом базовом runtime (например org.astra.mainPlatform) ia32-libs
в среде нет - тогда он попадает в приложение автоматически как обязательная
зависимость wine (источник repository или dependencies.additional:
[wine]). Это рабочий вариант, но сборка получается крупнее. Ещё один повод
предпочесть org.astra.Qt.
Предупреждение
SIGSYS при первом запуске. Стандартный seccomp-фильтр Flatpak блокирует
системные вызовы, нужные Wine (modify_ldt и др., а также ptrace для
wine-preloader). Без послаблений процесс падает с кодом 159
(128 + SIGSYS). Обязательно добавьте разрешения:
permissions:
allow: [multiarch, devel]
multiarch разрешает 32-битные syscalls, devel - ptrace.
Рекомендованные зависимости#
В Recommends пакета wine лежит то, без чего Wine работает наполовину:
Vulkan/OpenGL (Direct3D), GnuTLS (HTTPS и .NET), SDL2, CUPS (печать). Для игр и
сложных приложений включайте их:
dependencies:
includeRecommends: true
Для простых приложений (как PuTTY) рекомендованные пакеты не нужны - достаточно обязательных.
Подготовка окружения#
Подключите репозитории AstraFlatHub и установите инструменты AFT (см. раздел Начало работы в документации AFT).
Установите базовую среду выполнения и SDK:
$ sudo flatpak install -y astra-main org.astra.Qt//1.8.5 $ sudo flatpak install -y astra-ext org.astra.qtSdk//1.8.5
Для Wine удобнее всего
org.astra.Qt: этот runtime уже содержитia32-libsи большинство библиотек, от которых зависит Wine. Меньше зависимостей - меньше размер и быстрее сборка. Проверить покрытие можно командой:$ aft-app analyze --package wine --runtime org.astra.Qt --runtime-version 1.8.5
Установите Wine в систему - он нужен только для генерации эталонного префикса:
$ sudo apt-get install -y --no-install-recommends wine
Шаг 1. Получение Windows-приложения#
Скачайте дистрибутив приложения. В примере - портативный putty.exe:
$ curl -fsSL -o putty.exe \
"https://the.earth.li/~sgtatham/putty/latest/w64/putty.exe"
Шаг 2. Создание готового WINEPREFIX#
Создайте чистый префикс и поместите в него приложение.
$ export WINEPREFIX="$HOME/wine-template-prefix"
$ export WINEDLLOVERRIDES="mscoree,mshtml=" # не тянуть mono/gecko из сети
$ rm -rf "$WINEPREFIX"
$ wineboot -i # инициализация префикса
$ wineserver -w # дождаться завершения
$ mkdir -p "$WINEPREFIX/drive_c/Program Files/PuTTY"
$ cp putty.exe "$WINEPREFIX/drive_c/Program Files/PuTTY/putty.exe"
Если у вас установщик setup.exe - вместо копирования запустите его один
раз в этом префиксе: wine setup.exe и пройдите установку.
Перенесите готовый префикс в каталог сборки приложения:
$ mkdir -p wineapp-src
$ cp -a "$WINEPREFIX" wineapp-src/wineprefix-template
Шаг 3. Скрипт-обёртка запуска#
Создайте wineapp-src/launch.sh. Он разворачивает префикс при первом старте
(/app доступен только для чтения, префикс должен жить в данных приложения) и
запускает .exe.
#!/bin/sh
set -e
# Каталог данных приложения (сохраняется между запусками)
DATA="${XDG_DATA_HOME:-$HOME/.local/share}/org.astra.PuTTY"
export WINEPREFIX="$DATA/prefix"
export WINEDLLOVERRIDES="${WINEDLLOVERRIDES:-mscoree,mshtml=}"
export WINEDEBUG="${WINEDEBUG:-fixme-all}"
# Готовим префикс ровно один раз
if [ ! -f "$WINEPREFIX/system.reg" ]; then
mkdir -p "$DATA"
if [ -d /app/share/wineprefix-template ]; then
cp -a /app/share/wineprefix-template "$WINEPREFIX"
wineboot -u # перепривязать пути после переноса
else
wineboot -i # чистый префикс, если шаблона нет
fi
wineserver -w
fi
exec wine "C:\\Program Files\\PuTTY\\putty.exe" "$@"
Шаг 4. Манифест сборки#
Создайте wine-putty.yaml. Источник - каталог sourcedir: build-команды
раскладывают обёртку и шаблон префикса в /app. Сам Wine добавляется через
dependencies.additional.
version: "1.0"
metadata:
id: org.astra.PuTTY
name: "PuTTY (Wine)"
version: "0.83"
arch: amd64
branch: stable
runtime:
id: org.astra.Qt
version: "1.8.5"
sdk: org.astra.qtSdk
source:
type: sourcedir
sourcedir:
path: /home/user/wineapp-src
buildCommands:
- install -Dm755 launch.sh /app/bin/putty
- mkdir -p /app/share && cp -a wineprefix-template /app/share/wineprefix-template
dependencies:
analyze: true
includeRecommends: false # для игр/Direct3D поставьте true
additional: [wine] # докладывает Wine;
files:
command: putty
permissions:
sockets: [x11]
shares: [network, ipc]
devices: [dri, shm]
filesystems: [home]
allow: [multiarch, devel] # обязательно для Wine (иначе SIGSYS)
build:
sbom: true
cache: true
export:
repository: ./repo
Шаг 5. Сборка, установка, проверка#
$ aft-app validate wine-putty.yaml
$ sudo aft-app build wine-putty.yaml
$ flatpak remote-add --no-gpg-verify --if-not-exists myrepo ./repo
$ sudo flatpak install -y myrepo org.astra.PuTTY
$ flatpak run org.astra.PuTTY
Быстрая проверка, что Wine жив внутри песочницы (должно вернуть wine-10.0):
$ flatpak run --command=wine org.astra.PuTTY --version
При первом flatpak run префикс разворачивается в
~/.var/app/org.astra.PuTTY/data/org.astra.PuTTY/prefix и приложение
запускается.
Справочник разрешений#
Поле |
Значение для примера |
Назначение |
|---|---|---|
|
|
Обязательно для Wine. Послабление seccomp, иначе SIGSYS. |
|
|
Графика и звук Windows-приложения. |
|
|
|
|
|
Сеть (онлайн-приложения, игры) и IPC для X11. |
|
|
Доступ к файлам пользователя. |
Варианты#
- Установщик
setup.exe На шаге 2 вместо копирования запустите
wine setup.exeв эталонном префиксе, затем поправьте путь к.exeвlaunch.sh.- Портативное приложение без префикса-шаблона
Не кладите
wineprefix-template- веткаwineboot -iвlaunch.shсоздаст чистый префикс при первом запуске. Файлы приложения положите в/appbuild-командой и запускайте их по пути/app/....- .NET и HTML внутри Wine
Чтобы работали офлайн, добавьте пакеты в сборку:
dependencies.additional: [wine, wine-mono, wine-gecko].- Один файл вместо репозитория
Добавьте в
exportполеbundle: putty.flatpak- рядом с репозиторием соберётся одиночный файл.flatpakдля установки командойflatpak install putty.flatpak.
Полный пример: игра SuperTuxKart#
Разберём упаковку портативной 3D-игры. Отличия от примера с PuTTY:
приложение портативное - префикс-шаблон не нужен, обёртка создаёт чистый префикс при первом запуске (ветка
wineboot -i);игре нужен GPU, поэтому
includeRecommends: true(OpenGL/Vulkan) иdevices: [dri, shm];нестандартная структура архива - данные лежат отдельно от
.exe.
Загрузка#
Портативную Windows-сборку берём с GitHub (надёжный CDN):
$ curl -fsSL --retry 5 -o stk.zip \
"https://github.com/supertuxkart/stk-code/releases/download/1.5/SuperTuxKart-1.5-win.zip"
Распаковка#
Архив содержит сборки под несколько архитектур и отладочные символы
(.pdb, ~591 МБ). Берём только 64-битную сборку и общие данные, символы
выкидываем:
$ mkdir game
$ unzip -q stk.zip \
"SuperTuxKart-1.5-win/stk-code/build-x86_64/*" \
"SuperTuxKart-1.5-win/stk-code/data/*" -d game
$ mv game/SuperTuxKart-1.5-win/stk-code game/stk-code && rm -rf game/SuperTuxKart-1.5-win
$ find game -name '*.pdb' -delete
В итоге .exe лежит в game/stk-code/build-x86_64/bin/, а данные - в
game/stk-code/data/ (823 МБ).
Примечание
Игра ищет каталог data относительно расположения .exe (как в штатном
run_game.bat, который делает pushd в каталог сборки). Поэтому в
обёртке перед запуском обязательно cd в каталог с .exe - структуру
stk-code/{build-x86_64,data} нужно сохранить.
Обёртка launch.sh#
#!/bin/sh
set -e
DATA="${XDG_DATA_HOME:-$HOME/.local/share}/org.astra.SuperTuxKart"
export WINEPREFIX="$DATA/prefix"
export WINEDLLOVERRIDES="${WINEDLLOVERRIDES:-mscoree,mshtml=}"
export WINEDEBUG="${WINEDEBUG:-fixme-all}"
if [ ! -f "$WINEPREFIX/system.reg" ]; then
mkdir -p "$DATA"
wineboot -i # портативная игра - чистый префикс с нуля
wineserver -w
fi
cd /app/share/supertuxkart/stk-code/build-x86_64/bin
exec wine supertuxkart.exe "$@"
Манифест wine-supertuxkart.yaml#
version: "1.0"
metadata:
id: org.astra.SuperTuxKart
name: "SuperTuxKart (Wine)"
version: "1.5"
arch: amd64
branch: stable
runtime:
id: org.astra.Qt
version: "1.8.5"
sdk: org.astra.qtSdk
source:
type: sourcedir
sourcedir:
path: /home/user/stk-build
buildCommands:
- install -Dm755 launch.sh /app/bin/supertuxkart
- mkdir -p /app/share/supertuxkart && cp -a game/. /app/share/supertuxkart/
dependencies:
analyze: true
includeRecommends: true # OpenGL/Vulkan для 3D
additional: [wine]
files:
command: supertuxkart
permissions:
sockets: [x11, wayland, pulseaudio]
devices: [dri, shm] # dri - GPU обязательно
shares: [network, ipc]
filesystems: [home]
allow: [multiarch, devel] # обязательно для Wine
build:
sbom: true
cache: true
export:
repository: ./repo
Сборка и проверка#
$ aft-app validate wine-supertuxkart.yaml
$ sudo aft-app build wine-supertuxkart.yaml
$ sudo flatpak install -y myrepo org.astra.SuperTuxKart
$ flatpak run org.astra.SuperTuxKart
При первом запуске префикс создаётся за несколько секунд, игра находит данные и
пишет свой конфиг в drive_c/users/<user>/AppData/Roaming/supertuxkart/.
Примечание
В логе возможны некритичные предупреждения окружения
(Fontconfig error: Cannot load default config file,
ALSA lib ... Cannot access file /usr/share/alsa/alsa.conf). На запуск они
не влияют; при желании устраняются добавлением fontconfig / alsa в
dependencies.additional.