Distributing software

Lately I have been looking at ways of distributing the beta version of a piece of software written in C++. Basically, should we ship rpms and/or debs? Some sort of self-contained package? I have to take into account that a couple of the dependencies are not available on the usual repositories, as they are not publicly released either. Some other dependencies are available in some repositories (Fedora), but not in others (EPEL, Ubuntu, Debian).

There are a few “new” ways of shipping software with everything self-contained. Docker containers would be one example. However, this being a command-line tool for end-users, I do not think that would be the best way.

But, is it me, or it is even a bigger mess now to distribute software? There used to be a couple of ways (binaries, I mean), but now these containerized solutions are making everything more complicated. Now it is not deb or rpm, but rather deb, rpm, docker, Singularity, Flatpak, Snap, AppImage…? Oh my…

I went ahead and tried to actually package in all, or most of those solutions, to get a hang of them, and a better ground to compare. The summary can be seen on this table:

Packaging System Root Single file Centralized Easy to use
RPM/copr Fedora Yes No Yes (copr) Trivial
RPM/epel Fedora Yes No Yes (epel) Trivial
Deb Debian Yes No Yes (ppa) Trivial
Docker Any No Yes Yes (DockerHub) Hard
Singularity Linux No Yes No Trivial
Flatpak Linux No Yes Yes (Flathub) Medium
Snap Linux Yes Yes Yes (Store) Easy
AppImage Linux No Yes No Trivial
Homebrew Linux/MacOSX No - Yes (GitHub) Medium

Details

RPM/copr

sudo dnf copr enable "user/project"

RPM/epel/fedora

Deb

Docker

Singularity

Flatpak

Snap

AppImage

wget https://.../MyApp-x86_64.AppImage
chmod a+x MyApp-x86_64.AppImage
./MyApp-x86_64.AppImage --help

Handling the Python environment within the image is not trivial. We can not rely on the system Python version, as packages may be missing and, besides, there are ABI incompatibility between Python versions.

Homebrew/Linuxbrew

The same manifests can be used both in Linux and MacOSX. However, Linux binaries can not be specified on the same manifest file, as the MacOSX version will not recognize it (pity). The other way around is fine.

My conclusions

For Linux only, AppImage seems to be the most flexible option. Native formats as RPM or DEB are not easily portable between distributions, so they require a non trivial amount of maintenance.

If Fedora/CentOS/RHEL is good enough, copr can fit the bill.

Homebrew is a good option for MacOSX users. Guaranteeing that the software will compile in any computer at any given time may prove to be complicated. For instance, my tap was originally working, and when I wrote this document the linking of boost-python was broken 😒