Live data from Hacker News

The state of binary compatibility on Linux and how to address it

jangafx.com

121–130 of 145 posts

Re: The state of binary compatibility on Linux and how to address it

#123
post #47

Earlier quoted context omitted.

> adding an application (not just a program binary) is as easy as extracting a package into a folder and integrates with the rest of the system I have fond memories of installed Warlords Battle Cry 3, Warcraft 3, AOE2 etc. directories on flash drives, distributed to 20+ kids in high school (all using the same key). Good days.

Way off topic but you just reminded me of all the time I spent playing Warlords 3 (not Warlords Battlecry 3, the original Warlords games were turn-based). One cool feature it had that I'm surprised I haven't really seen other turn-based games do is a "play by email" option similar to correspondence chess, except you're just emailing save files back and forth and the game makes importing/exporting the save files via e…

PBEM was not uncommon in games from that era. The other title I can think of that had the same feature built-in was Age of Wonders.

Re: The state of binary compatibility on Linux and how to address it

#124

There is no distinction between system and program libraries in Linux. We used to pretend there was one before usrmigration, but that was never good to take seriously. The distro as packager model ensures that everything is mixed together in the filesystem and is actively hostile to external packaging. Vendoring dependencies or static linking improves compatibility by choosing known working versions, but decreases in…

> Even dns resolution on glibc implies dynamic linking due to nsswitch. Because, as far as I’ve heard, it borrowed that wholesale from Sun, who desperately needed an application to show off their new dynamic linking toy. There’s no reason they couldn’t’ve done a godsdamned daemon (that potentially dynamically loaded plugins) instead, and in fact making some sort of NSS compatibility shim that does work that way (eith…

> Witness Windows, which has little to no problem with multiple libcs in a process

Only so long as you don't pass data structures from one to the other. The same caveats wrt malloc/free or fopen/fclose across libc boundaries still applies.

Well, not anymore, but only because libc is a system DLL on Windows now with a stable ABI, so for new apps they all share the same copy.

Re: The state of binary compatibility on Linux and how to address it

#125

golang seems to manage being 100% statically linked (unless you go out of your way, by using plugins). It just forgoes the stuff that the article mentions glibc doing dynamic linking for, and does it the simple and direct way.

What do you use golang for? If your answer is only web-dev and if you don't touch anything GUI, system libraries, PAM or VPNs, you simply haven't compiled something complex enough.

Re: The state of binary compatibility on Linux and how to address it

#126
post #75

Earlier quoted context omitted.

Just because you are used to slow compilers doesn't mean fast ones are impossible. As I said in the original post, code optimisation can be done before compilation on the developers machine, so all that need be done on the target is a simple debug build. An example is Jonathon Blow's JAI compiler which compiles around 250,000 lines of code per second. Even on very slow hardware this is reduced to perhaps 80,000LoC/s,…

> An example is Jonathon Blow's JAI compiler I thought you were advocating "just distribute source code" – JAI is a closed-source language that, in its decade of development, has never been used for a significant project.

I fail to see how that relates to my using it as an example of a fast compiler. For that matter, my suggested approach doesn't need to to release source code, just some kind of programming language code. You could minify it, pre-optimise it, or do any number of things that would mean it isn't source code but instead becomes derived code (as I said in my original comment). Distributing textual code is not the same as being open source. I'm really just saying you should distribute something that isn't a platform specific blob with a fixed binary interface. You could, for instance, use LLVM IR code to achieve this, which is little more than a kind of portable assembly. LLVM can apply heavy optimisations to this code on the developer's machine, then take only the last step of code generation on the user's machine.

Re: The state of binary compatibility on Linux and how to address it

#127
post #59
post #46

Earlier quoted context omitted.

No, end users need not get involved, it could/should be handled by the operating system.

Gentoo? Compiling big packages takes ages.

Not Gentoo. The system I'm suggesting is one where you replace the linker with one which accepts a platform agnostic assembly code with similar semantics to C, and perhaps some additional tools for stack traversal to allow the implementation of garbage collected languages and exceptions. Compiling would be fast because the code you distribute would have already had optimisations applied to it in a pre-compilation step. It would also be automatic in the same way the present linker system is automatic.

Re: The state of binary compatibility on Linux and how to address it

#128
post #33

Windows having multiple C libraries has its own pain points, in particular it's difficult to ship binary libraries that return allocated memory to their consumer (you either need to have the library consumer allocate the memory, which probably explains why so many Win32 APIs have this behaviour, or allow alloc/free functions to be registered). Not to mention different C libraries having their own file handle, TLS, et…

Having consumer allocate the memory where possible has other benefits in that the consumer can use more efficient allocation techniques (stack, arenas etc), and given that Win32 API design goes all the way back to the earliest version of Windows running on very resource-limited PCs, that would be the main reason why.

However, in cases where this wasn't consistently feasible - e.g. COM - Windows instead mandates the use of a common API to manage memory: CoGetMalloc etc.

Re: The state of binary compatibility on Linux and how to address it

#129

So of the 3 glibc issues they link - one is about the format of symbol information in the actual ELF binaries which is only an issue if you are not using the standard libc functions for looking up symbols for some strange reason - one is an issue that impacts targeting a lower version of glibc from a higher one which is a configuration that was never supported (though usually fails more loudly) - the last one is a se…

I think the problem in a nutshell is that it's not trivial(?) to build an executable on a modern Linux distro that links against an old glibc version number (and if it is trivial then it needs to be better communicated). It is actually quite trivial when building with the Zig toolchain since you can simply append the requested glibc version to the target-triple (e.g. `-target aarch64-linux-gnu.2.xx`), but I think thi…

> I think the problem in a nutshell is that it's not trivial(?) to build an executable on a modern Linux distro that links against an old glibc version number (and if it is trivial then it needs to be better communicated).

I wouldn't say it's trivial, but it's not rocket science either. Basically there are two main approaches. One is to just build inside a chroot or container with a sufficiently old distro inside. This is generally the path of least resistance because your build system doesn't really have to have any awareness of what's going on. You just build normally inside the chroot/container. The main downsides with this approach are that it's kind of wasteful (you have a whole distro's filesystem) and if you want to use a newer compiler than what the old distro in question shipped with you generally have to build it yourself inside said chroot/container.

The other main approach is to use a sysroot. gcc and clang both take an optional --sysroot parameter which is an alternative root for header and library lookups. This lets you use a compiler on the normal host, but old headers and libs. You can also bake this parameter in when compiling gcc (and also I assume clang, but less sure there) if you want a dedicated cross-toolchain.

Re: The state of binary compatibility on Linux and how to address it

#130
Zig CC + Vulkan would solve most of these issues:

1. Zig's toolchain statically links with musl libc, producing binaries that depend only on the Linux kernel syscall ABI, not any specific glibc version.

2. This eliminates all the symbol versioning nightmares (`GLIBC_2.xx not found`) that plague distribution across different Linux systems.

3. Vulkan provides a standardized, vendor-neutral GPU API that's supported across all modern graphics hardware, eliminating driver-specific dependencies.

4. The resulting binary is completely self-contained - no external library dependencies, no version mismatches, no containerization needed.

5. You get forward AND backward compatibility - the binary will run on both ancient and cutting-edge distros without modification.

The only real limitation is for NVIDIA CUDA-specific workloads, where you'd still need their proprietary stack.

Furthermore, for those who prefer a higher-level API, Zig CC + WebGPU offers similar benefits with a simpler programming model, though with slightly less mature implementations and a possible small performance overhead.

Post reply on HN