Deploying libraries - Hall of Fame/Shame
We have been deploying applications for over 1 year already, so I thought I would rank how difficult it has been to deal with several common toolkits and libraries.
Inspired by Dolphin Emulator and OpenGL drivers - Hall of Fame/Shame
Excellent - SDL
Very easy to deploy, SDL does not have excessive dependencies and it is very configurable thru env variables. There was only one problem which SDL fixed quickly once I let them know.
Excellent - iced and glfw
We haven’t had do anything to deploying these without issue, they are just copy and paste pretty much, just bundle OpenGL and vulkan since it can use both. Also since iced is used by rust apps and those compile mostly static it makes them super easy to deploy in general. These two are mentioned together since we haven’t deployed that many applications that use these libraries.
Excellent - Chromium/electron
These are already very portable on their own and very very easy to deploy as result. The only issue we have encountered is that sometimes these load some binaries as libraries and we have to careful in those cases.
Excellent - flutter
These are relocatable always, in fact distros often need to put the application in dedicated directory in /usr/share or /usr/lib since they need a relative lib directory next to the binary to work.
Excellent - MESA
Very easy to deploy, plenty of env variables to configure it, lots of build options, more recently MESA now allows to build the radeon drivers without linking to LLVM which has resulted in a massive decrease of our AppImages as result. Vulkan/OpenGL ICD discovery is also handled automatically and it looks into XDG_DATA_DIRS among a ton of other locations to find those files. And the icd files support relative library locations to the icd file itself 👀
Excellent - pipewire
Needs PIPEWIRE_MODULE_DIR and SPA_PLUGIN_DIR to be made relocatable. Otherwise perfect for deployment, it does have some performance issues but with pipewire-jack though.
Good - Qt
Qt is very easy to make relocable, it supports a qt.conf file that accepts relative paths which prevents using the env variable QT_PLUGIN_PATH which is very problematic for child processes, Qt also looks into XDG_DATA_DIRS and several other locations to find its translation files, QtWebEgnine is super easy to dewploy as well.
The only reason it is not excellent is becuase deploying QML is a bit complicated since the .qml files have to deployed along with the libraries and determining which ones to add is a mess. Right now we just add all of qml when deployign qml as result of this.
Qt also often links to libicudata (30 MiB lib) even though the vast majority of applications do not need this, thankfully it can be disabled at compile time, but ideally this should be dlopened instead when needed.
Good - .NET
Surprisingly easy to deploy. We do not need to set environments variable to make it relocable, applications already rely on relative paths. Often times however dotnet apps need to be launched by a shell script with hardcoded paths that needs to be edited, as it is usually something like exec dotnet /usr/lib/app.dll "$@".
Good - libdecor
This would have been horrible a few years ago, but libdecor has really done a lot of improve its situation and they want to improve it more, so I will give them credit for that. I still think this library is totally useless, this wouldn’t be needed at all if GNOME was so retarded to not provide server side decorations…
Good - ffmpeg
We do not have to do anything to make this relocatable, it just works™, However ffmpeg directly links to a ton of libraries, which means a lot of bloat often gets added, thankfully this can be mitigated by buidling ffmpeg with those options disabled, but ideally ffmpeg should dlopen the libraries when needed, there is no need to link and load libx265 because your music players uses ffmpeg, just no…
Good - NVIDIA ??
This is a bit odd but I will mention it, we never need to bundle the nvidia drivers, nvidia releases its driver linking to a +10yo version of glibc, that means we can use that driver without issue. The only issues we have had nvidia specific are distros breaking stuff… and also that we need to make sure some ancient libs are present lol
I still see this idea on relying on host libraries as flawed, who knows what will happen in the future. Also a good chunk of the issues at sharun are issues related to the logic we have to use the nvidia driver, it has been a pain.
Mediocre - LLVM
Easy to deploy but it is insanely bloated, to the point that Valve had to make ACO for MESA and zig is moving away from it, you can build smaller versions of LLVM by limiting the targets with -DLLVM_TARGETS_TO_BUILD but this still results in a 60 MIB libray and it breaks compilers in the processes, and it rare cases it still breaks the binary that links to it for some reason so you have to ship the massive version with all the targets…
Bad - alsa
alsa doesn’t check XDG_DATA_DIRS to find its data directory, we have to set ALSA_CONFIG_PATH to the configuration file in that directory, which is hardcoded to look into /usr/share/alsa anyway lol and fixing that issue is a total mess since the file does not accept relative paths to its location, so you have to get the value of some env variable using what syntax this is, like this
Bad - GLIBC
glibc supports the LOCPATH env varaible but this doesn’t work with locale archives, This problem affects NixOS and they have to patch it so that locale-archives can be made relocatable. We also have to set GCONV_PATH and good luck figuring out which gconv plugin your app exactly needs, and when the plugin is missing there is no error about it, it is just totally random what happens
Bad - Gstreamer
It is insane how you can screw up a system that is modular? First it is very difficult to determine what Gstreamer plugin an application needs unless you already know it before hand since you built it, Gstreamer uses something called gst-plugin-scanner which opens every single gstreamer plugin on the system, so we cannot easily determine using strace what plugin an application needs. It needs 4 env variables to be made relocatable GST_PLUGIN_PATH, GST_PLUGIN_SYSTEM_PATH, GST_PLUGIN_SYSTEM_PATH_1_0 (lol?), and GST_PLUGIN_SCANNER.
Also sometimes the bloody thing needs ffmpeg to work, it is useless. Just use ffmpeg directly and do not bother with Gstreamer.
Bad - OpenSSL
This is a general failure of linux that there is no standard path to the certificates on the host, there is however a convention that most distros have the certificates in /etc/ssl/certs/ca-certificates.crt, that location is there in Alpine, Arch, Ubuntu, Fedora and even NixOS. For the distros that do not we have to play this game of finding the certs and setting a ton of variables. At least there are variables we can set, because the next project does not 😹
Horrible - p11kit
You need to recompile the library to enable environment variables to make it relocatable. And none of the vars are documented!
Horrible - WebKit
WebKit is hardcoded to load some binaries in /usr/lib which makes no sense and there is no way to override this location other than recompiling with a debug flag to expose a variable wtf. Sometimes it just dies depending on the OpenGL version you have, and with Nvidia you often have to set WEBKIT_DISABLE_DMABUF_RENDERER=1 and WEBKIT_DISABLE_COMPOSITING_MODE=1. Hopefully tauri will be able to replace it with servo in the future, because this is just bad…
Horrible - jack2
The library needs matching versions between server and client to work 1
pipewire-jack is often suggested as an alternative, but that has performance issues, so yeah you are very screwed up here. We do have a hook that lets use use the host jack2 when needed, but I cannot guarantee if this will keep working in the future.
Garbage - GTK
Where do I even start?
-
Every single GTK app has the path to its locales hardcoded at the prefix (
/usr/share/locale) and there no env variable to change this. -
it depends on stuff like Gio, gdk-pixbuf, glycin, which bloats the final application. And those projects have their own set of issues when made relocable. And in the case of glycin it is a total disaster..
-
The vulkan backend was totally broken wayland with intel gpus, before that we had to fix it by building GTK4 without the vulkan backend, as sometimes
GSK_RENDERER=gljust did not work as it ignores the variable, and in fact it looks like we will keep building GTK4 without vulkan as long as possible, because we also had an incident with one user on a super old intel laptop that does not support vulkan where gnome apps did not just work even withGSK_RENDERER=glwhile the apppimages we make did. -
All GTK apps also have a useless dependency to a 30 MiB libicudata library, which is needed by libxml which is needed by libappstream which why would you even need to link to libappstream at all?? This is used to make AppStream metadata used in software stores, dafuck?
-
It also depends on Gstreamer 😹
At least more recently they are looking into adding svg support into GTK4, which hopefully means they will get rid of the gdk-pixbuf and glycin dependency.
Garbage - Python
- Applications break horribly with the sightless version bump. 1 2
- cpython running
/sbin/ldconfig -pto find libraries, super broken. 1 2 3 - uv python breaks if you strip it 😹
- Builds randomly began to fail on the same python uv version and had to use this to it
- python apps are often written with a ton of hardcoded paths, even more than GTK apps, so a lot of manual patches are needed to fix them. This is the result of a language that suggests containers to work.
- Good luck figuring the dependencies of python apps, you often run into missing undeclared dependencies 1 2