Building a Flatpak
What is it about? #
I’ve been a proponent of Flatpaks since Fedora, because they actually run stress-free on every distribution without having to add additional package sources. Also, if you rely on a stable system like Debian, but still want to run more up-to-date applications than the package sources offer, Flatpak is excellent.
Since Fedora Silverblue or openSUSE MicroOS, Immutable Distributions are getting more interesting, because they offer some advantages and in my opinion are the right way to make GNU/Linux more attractive on the desktop. Flatpak is ideal as a software center for typical desktop applications without losing the distribution diversity.
Despite the extensive support, not all applications are available on Flathub. Technically, any application can be packaged as a Flatpak, but there is a lack of volunteers to cover the huge variety.
So that I can also give something back to the FLOSS community, I took a look at the newsreader SABnzbd. On the download page there are already some packages, including an RPM package, which requires the inclusion of a third party source. However, the version stored there is older than the current one and the repository was officialy created for Fedora 33.
How to begin? #
The official Flatpak documentation offers a good first start, which sounds quite simple at first: Build your first Flatpak.
Unfortunately the help is not sufficient for more extensive applications, since probably few want to package a shell script. Here is my summary and procedure for the packaging of SABnzbd. A more detailed information (naming conventions etc.) can be read in the official documentation.
Install environment (latest version 22.08) #
-
First install Flatpak itself
-
Install runtimes in the latest version 22.08:
flatpak install flathub org.freedesktop.Platform//22.08 org.freedesktop.Sdk//22.08I decided to use the latest version, because some Python runtimes are more recent here. This avoids conflicts I ran into before, more on that later.
- Create files
mkdir flatpak-sabnzbd
cd flatpak-sabnzbd
touch org.sabnzbd.SABnzbd.yml- Download Linux tarball and output hash value
wget https://github.com/sabnzbd/sabnzbd/releases/download/3.6.1/SABnzbd-3.6.1-src.tar.gz
sha256sum SABnzbd-3.6.1-src.tar.gzorg.sabnzbd.SABnzbd.yml #
Basically all the magic happens in the org.sabnzbd.SABnzbd.yml. Instead of YAML you can also use JSON, I chose the former because of readability.
nano org.sabnzbd.SABnzbd.ymlid: org.sabnzbd.SABnzbd
command: SABnzbd.py
runtime: org.freedesktop.Platform
runtime-version: '22.08'
sdk: org.freedesktop.Sdk
modules:
- name: sabnzbdplus
buildsystem: simple
build-commands:
sources:
- type: archive
url: https://github.com/sabnzbd/sabnzbd/releases/download/3.6.1/SABnzbd-3.6.1-src.tar.gz
sha256: e365e4581c594aac445b9fb229aa80c0a1ed299deca511045bb78bd55d2ece9eThis is how the basic structure would look like with customized values. SABnzbd is a Python application, so we will run SABnzbd.py.
As build system there are several options to choose from, I chose buildsystem: simple here. When we build the package, the archive is automatically unpacked.
However, we can’t do much with the config until now, so we complete the whole thing as follows:
id: org.sabnzbd.SABnzbd
command: SABnzbd.py
runtime: org.freedesktop.Platform
runtime-version: '22.08'
sdk: org.freedesktop.Sdk
finish-args:
- --socket=x11
- --share=ipc
- --share=network
- --talk-name=org.freedesktop.Notifications
- --talk-name=org.kde.StatusNotifierWatcher
- --filesystem=xdg-download
modules:
- name: sabnzbdplus
buildsystem: simple
build-commands:
- cp -r * /app/bin/
sources:
- type: archive
url: https://github.com/sabnzbd/sabnzbd/releases/download/3.6.1/SABnzbd-3.6.1-src.tar.gz
sha256: e365e4581c594aac445b9fb229aa80c0a1ed299deca511045bb78bd55d2ece9eSince Flatpak runs the applications isolated, we need to give some permissions in the finish-args field. The selected build system asks us for commands, I just said here that the unpacked content should be placed under /app/bin, which is the Flatpak program directory. Since SABnzbd does not need to be compiled, this fits so far.
We can trigger the build process and installation as follows:
flatpak-builder build-dir org.sabnzbd.SABnzbd.yml
flatpak-builder --user --install --force-clean build-dir org.sabnzbd.SABnzbd.yml
flatpak run org.sabnzbd.SABnzbd.ymlHowever, if we start the package, we get error messages because some Python dependencies are missing:
$ flatpak run org.sabnzbd.SABnzbdtut
Not all required Python modules are available, please check requirements.txt
Missing module: Cheetah
You can read more at: https://sabnzbd.org/wiki/installation/install-off-modules
If you still experience problems, remove all .pyc files in this folder and subfoldersInstall dependencies #
Since SABnzbd comes with some dependencies, it would be very time consuming to enter all the Python modules manually in the .yml config, so we use a more elegant way.
To find out which dependencies we need at all, we unpack the SABnzbd-3.6.1-src.tar.gz. There you will find a list of all dependencies in requirements.txt.
With the help of a Python application you can create an automatically generated config file, which generates all dependencies, including URL/hash value: flatpak-pip-generator
The generator will be downloaded and executed:
wget https://github.com/flatpak/flatpak-builder-tools/blob/master/pip/flatpak-pip-generator
python3 flatpak-pip-generator --requirements-file=requirements.txtAfter a few seconds we get a python3-requests.json, here is an excerpt:
{
"name": "python3-requirements",
"buildsystem": "simple",
"build-commands": [],
"modules": [
{
"name": "python3-sabyenc3",
"buildsystem": "simple",
"build-commands": [
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"sabyenc3==5.4.3\" --no-build-isolation"
],
"sources": [
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/c3/21/30c4111f7ad9188229b5c21f04881f845a507904cb8717368f79a4bfb845/sabyenc3-5.4.3.tar.gz",
"sha256": "7a2fd29d58383b2e9c0413f1835e2530c40181b351e0583469afbcb150536346"
}
]
},
{
"name": "python3-cheetah3",
"buildsystem": "simple",
"build-commands": [
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"cheetah3==3.2.6\" --no-build-isolation"
],
"sources": [
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/ee/6f/29c6d74d8536dede06815eeaebfad53699e3f3df0fb22b7a9801a893b426/Cheetah3-3.2.6.tar.gz",
"sha256": "f1c2b693cdcac2ded2823d363f8459ae785261e61c128d68464c8781dba0466b"
}
]
},
[...]We now include this in our org.sabnzbd.SABnzbd.yml config:
id: org.sabnzbd.SABnzbd
command: SABnzbd.py
runtime: org.freedesktop.Platform
runtime-version: '22.08'
sdk: org.freedesktop.Sdk
finish-args:
- --socket=x11
- --share=ipc
- --share=network
- --talk-name=org.freedesktop.Notifications
- --talk-name=org.kde.StatusNotifierWatcher
- --filesystem=xdg-download
modules:
- python3-requirements.json
- name: sabnzbdplus
buildsystem: simple
build-commands:
- cp -r * /app/bin/
sources:
- type: archive
url: https://github.com/sabnzbd/sabnzbd/releases/download/3.6.1/SABnzbd-3.6.1-src.tar.gz
sha256: e365e4581c594aac445b9fb229aa80c0a1ed299deca511045bb78bd55d2ece9eWe restart the build process, which takes a little longer for the first time:
rm -r build-dir/
flatpak remove org.sabnzbd.SABnzbd -y
flatpak-builder build-dir org.sabnzbd.SABnzbd.yml
flatpak-builder --user --install --force-clean build-dir org.sabnzbd.SABnzbd.ymlAnd run our application again to be greeted by the following error message:
$ flatpak run org.sabnzbd.SABnzbd.yml
[...]
2022-10-23 22:23:25,101::ERROR::[SABnzbd:450] par2 binary... NOT found!
2022-10-23 22:23:25,102::ERROR::[SABnzbd:465] unrar binary... NOT found!
2022-10-23 22:23:25,102::INFO::[SABnzbd:475] 7za binary... NOT found!
[...]Install other dependencies #
par2 binary #
Source:
https://github.com/flathub/org.gnome.FileRoller/blob/master/org.gnome.FileRoller.json
https://github.com/Parchive/par2cmdline
- name: gnustep-make
buildsystem: simple
build-commands:
- ./configure --prefix=/app
- make -j $FLATPAK_BUILDER_N_JOBS install
sources:
- type: archive
url: https://github.com/gnustep/tools-make/releases/download/make-2_9_0/gnustep-make-2.9.0.tar.gz
sha256: a0b066c11257879c7c85311dea69c67f6dc741ef339db6514f85b64992c40d2a
- name: gnustep
buildsystem: simple
build-commands:
- ./configure --prefix=/app
- make -j $FLATPAK_BUILDER_N_JOBS install
- ls /app/include
sources:
- type: archive
url: https://github.com/gnustep/libs-base/releases/download/base-1_28_0/gnustep-base-1.28.0.tar.gz
sha256: c7d7c6e64ac5f5d0a4d5c4369170fc24ed503209e91935eb0e2979d1601039ed
- name: unrar
buildsystem: simple
build-commands:
- make
- cp ${PWD}/unrar /app/bin/
sources:
- type: archive
url: https://www.rarlab.com/rar/unrarsrc-6.1.7.tar.gz
sha256: de75b6136958173fdfc530d38a0145b72342cf0d3842bf7bb120d336602d88edunrar binary #
Source:
https://www.linuxfromscratch.org/blfs/view/svn/general/unrar.html
- name: par2
buildsystem: simple
build-commands:
- ./configure --prefix=/app
- make
- cp ${PWD}/par2 /app/bin/
sources:
- type: archive
url: https://github.com/Parchive/par2cmdline/releases/download/v0.8.1/par2cmdline-0.8.1.tar.gz
sha256: 7b2fcc19b54c7080939fc2cbaca33ae40ac33759a526292933c94a85ba850d117za binary #
Source:
https://github.com/flathub/io.github.peazip.PeaZip/blob/master/formats/7-zip.yml
- name: 7-zip
buildsystem: simple
build-commands:
- |
for bundle in Alone2 SFXCon; do
pushd CPP/7zip/Bundles/${bundle}
make -j ${FLATPAK_BUILDER_N_JOBS} -f ../../cmpl_gcc.mak
popd
done
- install -Dm755 CPP/7zip/Bundles/Alone2/b/g/7zz $FLATPAK_DEST/bin/7z
- install -Dm755 CPP/7zip/Bundles/SFXCon/b/g/7zCon $FLATPAK_DEST/bin/7zCon.sfx
sources:
- type: archive
strip-components: 0
url: https://7-zip.org/a/7z2201-src.tar.xz
sha256: 393098730c70042392af808917e765945dc2437dee7aae3cfcc4966eb920fbc5Icons und Appinfos #
In order to get a decent launcher with icon, we need to make some adjustments here. I have oriented myself to already existing Flatpaks from GitHub.
build-commands:
- cp -r * /app/bin/
- install -Dm644 ${PWD}/linux/org.sabnzbd.sabnzbd.appdata.xml /app/share/appdata/$FLATPAK_ID.xml
- install -Dm644 ${PWD}/icons/logo-arrow.svg /app/share/icons/hicolor/scalable/apps/$FLATPAK_ID.svg
- install -Dm644 ${PWD}/linux/sabnzbd.desktop /app/share/applications/$FLATPAK_ID.desktop
- desktop-file-edit --set-icon=${FLATPAK_ID} /app/share/applications/${FLATPAK_ID}.desktop
- sed -i 's|Exec=/opt/sabnzbd/SABnzbd.py --browser 1 %F|Exec=SABnzbd.py|g' /app/share/applications/${FLATPAK_ID}.desktopFinal config #
org.sabnzbd.SABnzbd.yml
id: org.sabnzbd.SABnzbd
command: SABnzbd.py
runtime: org.freedesktop.Platform
runtime-version: '22.08'
sdk: org.freedesktop.Sdk
finish-args:
- --socket=x11
- --share=ipc
- --share=network
- --talk-name=org.freedesktop.Notifications
- --talk-name=org.kde.StatusNotifierWatcher
- --filesystem=xdg-download
modules:
- python3-requirements.json
- name: gnustep-make
buildsystem: simple
build-commands:
- ./configure --prefix=/app
- make -j $FLATPAK_BUILDER_N_JOBS install
sources:
- type: archive
url: https://github.com/gnustep/tools-make/releases/download/make-2_9_0/gnustep-make-2.9.0.tar.gz
sha256: a0b066c11257879c7c85311dea69c67f6dc741ef339db6514f85b64992c40d2a
- name: gnustep
buildsystem: simple
build-commands:
- ./configure --prefix=/app
- make -j $FLATPAK_BUILDER_N_JOBS install
- ls /app/include
sources:
- type: archive
url: https://github.com/gnustep/libs-base/releases/download/base-1_28_0/gnustep-base-1.28.0.tar.gz
sha256: c7d7c6e64ac5f5d0a4d5c4369170fc24ed503209e91935eb0e2979d1601039ed
- name: unrar
buildsystem: simple
build-commands:
- make
- cp ${PWD}/unrar /app/bin/
sources:
- type: archive
url: https://www.rarlab.com/rar/unrarsrc-6.1.7.tar.gz
sha256: de75b6136958173fdfc530d38a0145b72342cf0d3842bf7bb120d336602d88ed
- name: par2
buildsystem: simple
build-commands:
- ./configure --prefix=/app
- make
- cp ${PWD}/par2 /app/bin/
sources:
- type: archive
url: https://github.com/Parchive/par2cmdline/releases/download/v0.8.1/par2cmdline-0.8.1.tar.gz
sha256: 7b2fcc19b54c7080939fc2cbaca33ae40ac33759a526292933c94a85ba850d11
- name: 7-zip
buildsystem: simple
build-commands:
- |
for bundle in Alone2 SFXCon; do
pushd CPP/7zip/Bundles/${bundle}
make -j ${FLATPAK_BUILDER_N_JOBS} -f ../../cmpl_gcc.mak
popd
done
- install -Dm755 CPP/7zip/Bundles/Alone2/b/g/7zz $FLATPAK_DEST/bin/7z
- install -Dm755 CPP/7zip/Bundles/SFXCon/b/g/7zCon $FLATPAK_DEST/bin/7zCon.sfx
sources:
- type: archive
strip-components: 0
url: https://7-zip.org/a/7z2201-src.tar.xz
sha256: 393098730c70042392af808917e765945dc2437dee7aae3cfcc4966eb920fbc5
- name: sabnzbdplus
buildsystem: simple
build-commands:
- cp -r * /app/bin/
- install -Dm644 ${PWD}/linux/org.sabnzbd.sabnzbd.appdata.xml /app/share/appdata/$FLATPAK_ID.xml
- install -Dm644 ${PWD}/icons/logo-arrow.svg /app/share/icons/hicolor/scalable/apps/$FLATPAK_ID.svg
- install -Dm644 ${PWD}/linux/sabnzbd.desktop /app/share/applications/$FLATPAK_ID.desktop
- desktop-file-edit --set-icon=${FLATPAK_ID} /app/share/applications/${FLATPAK_ID}.desktop
- sed -i 's|Exec=/opt/sabnzbd/SABnzbd.py --browser 1 %F|Exec=SABnzbd.py|g' /app/share/applications/${FLATPAK_ID}.desktop
sources:
- type: archive
url: https://github.com/sabnzbd/sabnzbd/releases/download/3.6.1/SABnzbd-3.6.1-src.tar.gz
sha256: e365e4581c594aac445b9fb229aa80c0a1ed299deca511045bb78bd55d2ece9eHow to build #
flatpak install flathub org.freedesktop.Platform//22.08 org.freedesktop.Sdk//22.08
flatpak-builder build-dir org.sabnzbd.SABnzbd.yml
flatpak-builder --user --install --force-clean build-dir org.sabnzbd.SABnzbd.yml
flatpak run org.sabnzbd.SABnzbdFeel free to contribute or clone the code in my GitHub repository.