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?

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