Quantcast
Channel: John Ramsden
Viewing all articles
Browse latest Browse all 24

Packaging Wine Application 'Path of Exile' With Flatpak

$
0
0

I enjoy gaming and occasionally there’s an application I want to run that is unavailable on Linux. Up until now my primary way of dealing with this was to use multiple wine bottles, one for each game. While this provides a little bit of segmentation for applications, it is not a sandbox.

Something else I dislike is how wine likes to spit out files all over my filesystem. There are ways to stop wine from doing this, such as disabling wine’s winemenubuilder by setting an environment variable with WINEDLLOVERRIDES="winemenubuilder.exe=d".

However I also don’t want my wine bottle having access to my entire system.

I figured this would be a good opportunity to test out flatpak, and figure out how to package and build a wine application with it.

The nice thing about using flatpak is that everything will be isolated in the sandbox. For complex or proprietary applications, flatpak might make packaging possible, when it wasn’t before, or at least was very difficult.

I took a crack at building a flatpak for Path of Exile - which is only available for Windows - that can be installed from my repository. So far everything is working successfully, and it has made installing on multiple Linux systems as simple as installing a regular Linux package.

pathofexile

If you’re mostly interested in trying out the flatpak, instructions for installing it are available at the bottom of the post.


Index

Creating the Build

The first step to creating a Flatpack is initializing a ‘build’. A gpg key can be used to sign the resulting package. Alternatively the flag --no-gpg-verify can be given to not require this.

Since Path of Exile is a 32-bit application I will be using the i386 GNOME platform and runtime.

flatpak build-init pathofexile ca.johnramsden.pathofexile org.gnome.Platform/i386/3.28 org.gnome.Sdk/i386/3.28

A local repository should also be set up.

flatpak --user remote-add --if-not-exists johnramsden applications

This creates the johnramsden repository in an applications directory.

flatpak-builder

Creating an flatpak is easy with flatpak-builder. Instead of doing the individual steps manually to create a build, flatpak-builder can be used to save the configuration in a json file and build the Flatpak.

Create a json file in reverse DNS format. Mine will be ca.johnramsden.pathofexile.json. The entire file can be found on GitHub.

General Options

To start, add a few self-explanitory values.

{"app-id":"ca.johnramsden.pathofexile","runtime":"org.gnome.Platform/i386/3.28","sdk":"org.gnome.Sdk/i386/3.28","tags":["proprietary"],"command":"pathofexile.sh",...

The command will be a script that will be run at start.

Next set some global build options.

"build-options":{"env":{"WINEPREFIX":"/var/data/.local/share/pathofexile","WINEDLLOVERRIDES":"mscoree=d;mshtml=d","V":"0"}}

Inside the Flatpak, data that is persistent can be saved in /var/data, the actual location of the data will be ${HOME}/.var/app/ca.johnramsden.pathofexile/, but inside the Flatpak it can be referenced with /var/data.

finish-args

Next specify some finish-args. These are very important and will specify the final permissions the application has on a system.

"finish-args":["--persist=.local/share/pathofexile","--socket=x11","--share=network","--share=ipc","--device=dri","--allow=multiarch","--socket=pulseaudio","--filesystem=/var/log:ro","--env=WINEDEBUG=-all","--env=WINE_RESOLUTION=1920x1080"]

Several of them are fairly self-explanatory, but I will explain each of them.

  • --persist=.local/share/pathofexile
    • Bindmount the homedir-relative path .local/share/pathofexile to ${HOME}/.local/share/pathofexile during runtime.
    • The actual directory lives at the corresponding path in the per-application directory, i.e. ${HOME}/.var/app/ca.johnramsden.pathofexile/.local/share/pathofexile. This allows a persistent directory to be set for data that will be needed at runtime.
    • Since we set our WINEPREFIX to /var/data/.local/share/pathofexile, this will be the location of our wine bottle.
  • --socket=x11
    • Allow graphical access to the xorg server.
  • --share=network
    • Allow network access.
  • --share=ipc
    • Allow inter-process communication.
  • --device=dri
    • Allow access to graphics direct rendering.
  • --allow=multiarch
    • Allow 64 and 32-bit applications to be built.
  • --socket=pulseaudio
    • Use pulseaudio.
  • --filesystem=/var/log:ro
    • Allow read-only access to /var/log. This is used to check the amount of video card memory in the startup script.
  • --env=WINEDEBUG=-all
    • Do not show wine debugging output, this increases performance.
  • --env=WINE_RESOLUTION=1920x1080
    • Allow users to set the resolution at runtime using an environment variable. Defaults to 1920x1080.

modules

The Next Step will be to add modules needed to run the application.

I use the following modules in my application:

  • wine
  • winetricks
  • cabextract
  • wine-gecko
  • wine-mono
  • wget
  • pathofexile-installer
  • icons
  • desktop
  • metadata

Each of them downloads and if necessary compiles the application, installing it into the Flatpak. Special integration exists for autotools, but simple commands such as make install can also be used.

The last four are just installing a script, icons, a desktop file, and AppStream metadata. The only one key to the functioning of the flatpak is the pathofexile-installer module.

The following is an example of the module I use to compile and install wine.

"name":"wine","buildsystem":"autotools","build-options":{"make-args":["--silent"]},"sources":[{"type":"archive","url":"https://dl.winehq.org/wine/source/3.x/wine-3.4.tar.xz","sha256":"a483247ac93f325d623a463438590b7355ec26c670af15d356b0ce6c46398e93"},{"type":"archive","url":"https://github.com/wine-staging/wine-staging/archive/v3.4.tar.gz","sha256":"c56f5d2706e228fe4f720e9301af30e82b4a7b6c1749d0b6170e60f1cb16fe34"},{"type":"shell","commands":["./patches/patchinstall.sh DESTDIR=$(pwd) --all"]}]

Tthe “pathofexile-installer” module contains the script required to set up the wine bottle, download Path of Exile, and install it into the wine bottle.

#!/bin/bashexport WINEPREFIX="${HOME}/.local/share/pathofexile"export WINEDEBUG=-allPOE_INSTALLER_NAME="pathofexile_setup.exe"POE_SETUP="${WINEPREFIX}/${POE_INSTALLER_NAME}"POE_DOWNLOAD_URL='https://www.pathofexile.com/downloads/PathOfExileInstaller.exe'WINE_RESOLUTION="${WINE_RESOLUTION:-1920x1080}"WINE_CMD="/app/bin/wine"XORG_LOG="/var/log/Xorg.0.log"echo"######################################"echo"## Path of Exile Unofficial Flatpak ##"echo"######################################"echo# Set video memory by checking xorg
set_video_memory(){if[-f"${XORG_LOG}"];then
    VIDEO_MEMORY=$(($(sed -rn's/.*memory: ([0-9]*).*kbytes/\1/gpI'${XORG_LOG})/1024))echo"Setting video memory to ${VIDEO_MEMORY}"tmpfile=$(mktemp VideoMemory.XXXXX.reg)cat<<EOF> "${tmpfile}"
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\\Software\\Wine\\Direct3D]
"VideoMemorySize"="${VIDEO_MEMORY}"EOF
     wine regedit ${tmpfile}
     rm ${tmpfile}else
    echo"Unable to read Xorg logs from ${XORG_LOG}."echo"Leaving video card memory at default settings."fi}# Run only if POE isn't installed
first_run(){echo"Path of Exile not installed, Installing first run wine requirements."
  winetricks --unattended directx9 usp10 msls31 corefonts tahoma win7

  echo"Running first run settings."
  winetricks --unattendedcsmt=on glsl=disabled

  if[!-f"${POE_SETUP}"];then
    echo"Downloading Path of Exile installer."
    wget --output-document="${POE_SETUP}"${POE_DOWNLOAD_URL}fi
  echo"Running Path of Exile installer.""${WINE_CMD}""${POE_SETUP}"}

startup(){echo"Setting resolution to ${WINE_RESOLUTION}"echo"If resolution was changed from default, game may need restarting"
  winetricks --unattendedvd=${WINE_RESOLUTION}echo

  set_video_memory

  if!grep-q'Software\\\\GrindingGearGames\\\\Path of Exile'${WINEPREFIX}/user.reg;then
    first_run 
  fi

  echo;echo"Starting Path of Exile..."${WINE_CMD}"${WINEPREFIX}/drive_c/Program Files/Grinding Gear Games/Path of Exile/PathOfExile.exe"\
    dbox  -no-dwrite-noasync}

startup

The script gets run at startup, makes sure Path of Exile is Installed, otherwise it must be the first run, therefore install dependencies and download and install path of Exile.

Doing the install this way, I haven’t actually packaged Path of Exile, i’ve essentially packaged everything required to install it in a wine bottle on the first run.

The flatpak-builder module for it is as follows.

"name":"pathofexile-installer","buildsystem":"simple","build-commands":["install --directory ${WINEPREFIX}","install pathofexile.sh /app/bin"],"no-make-install":true,"sources":[{"type":"file","path":"pathofexile.sh"}]

Build the Flatpak

Once the package is finished, run flatpak-builder to create the resulting package (gpg signing is optional).

flatpak-builder --user \
                --force-clean \
                --repo=applications \
                --gpg-sign=${GPG_KEY} pathofexile ca.johnramsden.pathofexile.json

When it’s finished, it will be exported to the applications repo.

Remainder of flatpak-builder manifest

My repo containing the build instructions can be found on github. It contains:

.├── ca.johnramsden.pathofexile.appdata.xml
├── ca.johnramsden.pathofexile.json
├── pathofexile-256.png
├── pathofexile.desktop
├── pathofexile.sh
├── README.md
└── settings.conf

I tried to highlight the interesting parts above.

Install my Flatpak

If you want to try my flatpak without having to build it yourself, add my Flatpak repository.

flatpak --user remote-add \--if-not-exists johnramsden http://flatpakrepo.johnramsden.ca/johnramsden.flatpakrepo

Now you should be able to install my flatpaks.

flatpak --user install johnramsden ca.johnramsden.pathofexile

If you are missing the GNOME platform you may need to add the flathub or gnome repository and install it.

flatpak --user remote-add \--if-not-exists flathub \
    https://flathub.org/repo/flathub.flatpakrepo
flatpak --user install flathub org.gnome.Platform//3.28

To change the virtual desktop resolution, set the environment variable WINE_RESOLUTION in the run command.

It defaults to 1920x1080, to set it to 720x480 for example you would change the run command to:

flatpak run --env=WINE_RESOLUTION=720x480 ca.johnramsden.pathofexile

To make it permanent edit the ~/.local/share/flatpak/exports/share/applications/ca.johnramsden.pathofexile.desktop file.

If you think I’ve made a mistake or would like to submit a pull request, please visit the GitHub repository.

Automated Builds

I also set up an automated system using Travis CI for building the flatpak upon push to github, and a GitHub pages site for distribution. In my next post I will describe how it is configured.


Viewing all articles
Browse latest Browse all 24

Trending Articles