Linux Apps That Maybe Run Linux software distribution remains fragmented, with experts divided between containerized apps and granular permission models, while shared library soname bumps frequently break applications after OS updates, frustrating developers accustomed to Windows' simpler model. Linux Apps That Maybe Run Latest update: According to some prominent fellows, whom I won't name to protect the guilty, the only viable way to distribute software for Linux is to ship a container. Not to make an rpm/deb & serve it from a repo, like some insignificant companies that control half of the Internet do, but to collect all or most dependencies & put them alongside the application. Only this way, experts say, guarantees a high probability of surviving in the Linux wilderness. Another set of leading figures argue that shipping a container is necessary but not sufficient: in the days of rogue AI agents & catastrophic vulnerabilities hiding in every software corner, an application should some insists on the word must be incapable of doing anything without the user's permission. I thought about that a little, & came to the conclusion that a layperson couldn't care less. I'm not talking about a guy who feels personally offended when an ntp client dares to send a udp packet without asking first, I'm talking about an individual who downloads an "app" not to enjoy perusing a granular permission model, but to accomplish a task. I noticed how not a few Windows developers are at a loss to what to make of Linux software distribution models. This post is for them. Not a GUI Theoretically , if you write simple network microservices, you can abandon all 3rd-party libraries, even libc itself, & stick to syscalls of the Linux kernel ABI. As long as Linus is in charge, your programs will always work. Out of curiosity, I once tried to write a simple nolibc TCP server & described the experience https://henry-flower.dreamwidth.org/521944.html . For convenience, the text is in Ukrainian. Now, let's get back to real life. DLLs & sonames In the Linux world a DLL is called a shared library . A plain stock Fedora Live ISO with no developer tools installed, contains thousands 3977 in f44 of them. The 2 major Linux GUI toolkits GTK & Qt use a multitude of 3rd-party shared libraries that they don't control, & when you link against a GUI library in a particular distro, there is 0 guarantees that your program will work in the next distro release. Even if the shared libraries of the GUI toolkit stay the same, some transitive dependency may acquire a soname bump , & a dynamic linker will refuse to run your program. A shared library named foo has actually several names, that look different to various library consumers: - you use -lfoo argument when you invoke a linker to link your program against the foo library; - during that building step, the linker searches for libfoo.so file in a set of known directories ; - while the source code of the library could live across many files of arbitrary names, a build step that produces the library itself, puts the result in libfoo.so.x.y.z file. - when you invoke your program, the dynamic linker searches for libfoo.so.x file in a set of known directories . The last name, libfoo.so.x , e.g., libfoo.so.3 , is called the soname , & contains the major version number. Thus, the infamous soname bump means an increment of that number, due to incompatible changes in ABI. As soon as it happens, you're required to rebuild your program. On certain occasions you may cheat, symlinking libfoo.so.3 to a new libfoo.so.4 , but no user does that, your application just stops working after an OS update. Here is an example for giflib package on Fedora. As usual, to irritate newcomers, the library is split between 2 packages: bash $ rpm -ql giflib giflib-devel | grep .so | xargs stat -c %N '/usr/lib64/libgif.so.7' - 'libgif.so.7.1.0' '/usr/lib64/libgif.so.7.1.0' '/usr/lib64/libgif.so' - 'libgif.so.7' $ objdump -p /usr/lib64/libgif.so.7.1.0 | grep -i soname SONAME libgif.so.7 The program ld.so the dynamic linker, at the time of writing /lib64/ld-linux-x86-64.so.2 looks for libgif.so.7 . A linker, during a build step, uses libgif.so no version number . The latter file is absent in the user-faced giflib package. Living on the edge If you listen to proponents of assorted form of containerisation long enough, you may think that soname bumps or other events of ruinous nature happen every week. In reality, even rather old versions of fairly complex programs like Google Chrome, despite being designed to be updated daily, run ~fine on current Linux. E.g., I fished out a .deb variant of Chrome 71 Dec of 2018 , unpacked it & successfully ran the ancient browser on Fedora 44. It was linked against GTK3 modern Chrome doesn't use GTK , a toolkit that any distro will continue to ship for at least 20 years. Not all applications are that lucky, though. If you have a program compiled during the forgotten v1.0.x OpenSSL years, chances that a regular user would have skills to find or more precisely, bother to look for, unless extremely motivated a compatible .so file is practically nil. Here comes a point, where 2 schools of thought appear: You rely on dependencies target distros provide, rebuilding the program when the time comes. The movement attracts too few adherents nowadays, & we won't talk about it, for this philosophical tradition is considered passé in high society. You protect yourself from the disappearance of old shared libraries from the repos by shipping the most fragile of them with the program. How do you know which ones should be brought in? You don't, & resort to guessing. AppImage In the Windows world you can put necessary DLLs in the same directory with the executable. In Linux, by default, the dynamic linker searches for .so files exclusively in a predefined set of directories, reconfigurable only by a superuser. A temporal meaning, it has a long life fix for changing the directory lookup is to invoke ld.so manually, or set LD LIBRARY PATH env variable. This requires a tiny shell wrapper for a program executable, & this is what every developer starts with when he thinks about the chilling software distribution on Linux . What do you do after putting everything under 1 directory? In the distant past, folks would create a .tar.gz file with a content like so: foobar/ many files in this directory foobar.sh README The user would unpack the archive, ignore the readme, & run foobar.sh . By today's standards this is regarded as too confusing. First of all, what is this .tar.gz, a Japanese nesting doll? Second, a user vainly tries to start foobar.sh from within a GUI archiver app. In 2010s, there was a popular feeling that "something has to be done" about motley tarballs, hence a bunch of solutions appeared. One of the few survivors is AppImage, even though back in ~2016, when it hit the Linux scene hard, many decided it was "unnecessarily complicated" https://news.ycombinator.com/item?id=11187622 . I don't find it complicated at all. To show how it works, we'll ① write a hello world program that acquires the word "World" from a shared library, ② make an "appimage" from the program. Our source code: bash $ cat libfoo.c char greeting { return "World"; } $ cat app.c include