Linux backward compatibility really sucks. I still don't understand why fedora binaries can't run that easily on debian.
Linux backward compatibility really sucks. I still don't understand why fedora binaries can't run that easily on debian.
Tried three games so far -- Cook, Serve, Delicious 2 (2017), Nuclear Throne (2013) and uh, another one (201x): all of them refused to start, lacking one shared library or another.
I got CSD2 to start by copying .so files around and using LD_LIBRARY_PATH but it still did not work properly. Whatever. Bizarrely, it may be easier to get the respective Windows binaries to start in Wine. But I'm really past "getting things to work", there's enough stuff out there that doesn't require those kind of summoning rituals.
If CSD2 or Nuclear Throne had been released as open source software, chances are somebody would have updated their dependencies and they'd run fine. Heck, I'm a developer, I could probably have fixed it myself. But they're proprietary, and have gotten stale, and are a pain to get working. So I guess it's more of an incompatibility between the two models than an attribute of the bazaar.
[1] an old thing that's valued in the Cathedral, if at all, then only as a curiosity
Steam kinda got around this by providing a standard base of libraries Linux games could link against that would be the same on every distro, but even there some developers STILL assume that everyone has the same libraries as their Ubuntu system.
- it has nothing to do with "backward" compatibility
- it has nothing to do with Linux. If you change shared libraries with incompatible versions software will break on windows and bsd as well
It could be nice to not have to worry about all that compatibility and even some upgrade-issues that inevitably ensue. Though the costs can quickly outweigh the benefits, ie. as in the awfulness of "snap" and similar.
Windows do have compatibility and emulation layers, though some older software may still have some issues, it often works. Security-wise it's a good idea to keep patches and upgrades fresh.
And it's only Linux that has that problem in that dimension. Windows just kept everything around. Other systems don't evolve as much as Linux has, and they do not have the distribution differences that kill compatibility on Linux.
AppImage is great and solves that problem. It should be used more.
There are examples of binaries written against a UNIX kernel from 30 years ago that run just fine.
If you start adding dependencies on libraries you are choosing to have one of these problems:
- use dynamic libraries and refuse to cooperate with maintainers and things will break, rightfully so
- use dynamic libraries and the OS keep them around forever and it will become a security dumpster fire over time (and also will never scale down to embedded systems and phones)
- use dynamic libraries and ship them in a tarball and it will become a security dumpster fire over time
- use static libraries and it will become a security dumpster fire over time, plus it's even more difficult to tell what libraries are used
- use dynamic libraries and ship them with docker or appimage or similar and it will become a security dumpster fire over time, plus you have unnecessary complexity
- use dynamic libraries and package your stuff properly. Target LTS releases. Most good distributions will guarantee 5 years of stability of all the dependencies without version changes. Plus you get free backported security fixes and free testing.
> And it's only Linux that has that problem in that dimension
Not at all.
> AppImage is great and solves that problem. It should be used more.
Not at all.
I don't see why as long as you output an ELF file an App can't run. Maybe AppImage does that.
Note that it wasn't until GCC 10 (2020) that you could implement ELF symbol versioning without using an ugly inline asm hack in your function definition. From the GCC 10 release notes at https://gcc.gnu.org/gcc-10/changes.html:
> The symver attribute can be used to bind symbols to specific version nodes on ELF platforms. This is preferred to using inline assembly with GNU as symver directive because the latter is not compatible with link-time optimizations.
In combination with confusion around the differences between file suffix versioning, soname versioning, and symbol versioning, it's not surprising few developers even attempt to get this right. OTOH, most ABI breakages are because of dumb mistakes early on or gratuitous changes to the API. If you commit to API stability from the beginning, then ABI stability can and will come more naturally, at least for C code. Versioning of any sort becomes less complicated and even less important.[1] C++ is different because of how heavily header-defined templates are used these days.
[1] In other words, if you think API and ABI stability is principally a question of versioning, such as semantic versioning, you're doing it wrong. Commit to 100% backward compatibility at the API level and the answers to most of your design dilemmas become obvious. With the reduced cognitive burden, minding ABI compatibility becomes easier.
That has really not been my experience.
I've consistently hit problem with older software not running because it detected an incompatible version of GLIBC.
I've often had issues with compiling, either because of unwarranted assumptions in the third-party projects or because glibc made changes to their absurdly complex naming and feature gating hacks in their header files.
But glibc uses symbol versioning so even if the prototype of function foo changes, older software built against version X.Y should still link to fooX.Y at runtime. I don't follow glibc closely enough to know how many times they've accidentally broken things, though. I'm sure it's happened.
More complex runtime behaviors, like with the DNS resolver, are definitely common, but usually it's debatable whether glibc is fairly blameworthy.
Man i did not knew that.....