Distributing Binaries on Linux

May 16, 2020

When I ported Sky Checkers to Linux a decade ago, distributing binaries to users on the platform was a painful experience. Now, the situation has improved a little. Last week I released Sky Checkers binaries for Linux on the Snap Store and Flathub. I will discuss what distribution approaches I looked at and why I ultimately decided to distribute my software through these channels.

Dependency Bundling

The first approach for distributing my software I looked into is static linking. Initially I wanted to only statically link 3rd party dependencies but distinguishing which of my linked dependencies on my system are 3rd party is not straightforward. This lead me to statically link all libraries including glibc, which should be statically linked anyway for compatibility sake. However, static linking does not integrate with the system correctly for functions in glibc such as gethostbyname() or anything from OpenGL. Furthermore, the Linux ecosystem has resistance towards static linking, making it more painful when I have to chase down static versions of libraries not readily available.

I also explored bundling dynamic libraries and creating a wrapper shell script that set the dynamic loader path, but this approach has the same drawbacks with additional complexity. I also did not want to create or run a shell script.

These approaches may also require a developer to be compiling on the oldest version of a distribution they intend to support, which I want to avoid out of principle.

Thus distributing precompiled binaries, whether as a .deb, .rpm, or from a tgz archive, is not great.

Traditional Package Management

I briefly looked at traditional package management options such as distributing my software through Debian and RPM. I was turned off by the lack of simple documentation and processes involved as well as political concerns; for example, I wanted to distribute non-free data assets and that had implications on what channels my software can be distributed through. The process on the surface also appeared to be slow. Furthermore, a developer can’t ensure that a user can install the most recent version of a library required for the best user experience. I am not the only one that finds this experience painful. Listen to Linus’s rant.

Additionally, software that becomes delivered through these channels may not be easy to install. If installing software requires command line usage on popular user friendly distributions, then that’s not acceptable.

Some free software I’ve seen also passes responsibility of maintaining packages to volunteers of a Linux distribution. This is also not ideal. The developer should be responsible for maintaining packages for all distributions and maintenance should not be a burden. Updates to software should be in sync with all supported distributions.

AppImage

AppImage allows a developer to create a binary with bundled dependencies that can run anywhere without additional setup.

This technology looks nice but has a few drawbacks for production. The first drawback is the lack of desktop integration out of the box on popular distributions. The second one is making users set the executable bit of an AppImage they download online. The last one is producing an AppImage requires the developer to be on an old enough system with older versions of system libraries installed, which I want to avoid.

Snap & Flatpak

Snap and Flatpak are finally what I ended up on in this day and age. They allow the developer to specify what dependencies to bundle and allow specifying a base runtime of libraries to use, which makes compatibility more deterministic. They also have software centers that are embraced by popular distributions which makes installation friendly there. Lastly, they make shipping closed source software more of a possibility.

Unfortunately, two of these competing technologies exist. Maybe some day Canonical will give up on Snap and migrate onto Flatpak, although I do like snaps in some ways better.

Conclusion

Ultimately, none of the approaches except for distributing through the Snap Store and Flathub worked well for me. This is due to lack of control, ease of use, binary stability, politics, etc.

Unfortunately, Snap and Flatpak have issues on their own such as bloating software sizes, slowing down application launches, having a much to be desired sandboxing model, and perhaps UI integration issues. They also receive a bad reputation from users that may be unaware or do not sympathize about the painful state of distributing software on Linux.

Some users may also believe these packages are bad from a security point of view for not allowing distributions to update vulnerabilities in dependencies. My take is that developers should be managing vulnerabilities in their application code and in their dependencies. I do not trust library authors for maintaining compatibility despite their best efforts nor want to look out for defects or missing features in old libraries users may install. Software distribution on macOS and Windows gets this right; apps bundle 3rd party dependencies and they are maintained by the developer. Snap and Flatpak packages may also provide limited degree of sandboxing which makes assessing security not so black and white.

Overall, although Snap and Flatpak have significant issues, the other alternatives for distributing applications tend to be worse off from my perspective. Hopefully distributing software on Linux will further improve in the next decade.