Hacker News new | past | comments | ask | show | jobs | submit login

This problem is related to the fact that Linux distos typically dynamically link executables and don’t retain older versions of those libraries vs Windows which does.

It’s on of the many reasons Windows base install is so much heavier than a typical Linux base install.

The reason Windows retains older versions of executables while Linux doesn’t is because Windows doesn’t have a package manager like Linux distros. Ok, there’s now Windows Store plus a recent-ish CLI tool that was based on one of the many unofficial package managers, but traditionally the way to install Windows application was via manual downloads and installs. So those installers would typically come bundled with any shared libraries they’d need and often have those shared libraries in the application directory. Leading to lots of duplication of libraries.

You could easily do the same thing in Linux too but there’s less of a need because Linux distribution package managers are generally really good. But some 3rd party package managers do take this kind of approach, eg Nix, Snap, etc.

So it’s not that Linux is “unstable” but more that people have approached the same problem on Linux in a completely different way.

The fact that drag-and-drop installs work on macOS demonstrates that there isn’t really a UNIX-like limitation preventing Windows-style installs. It’s more that Linux distributions prefer a different method for application installation.




It's not just about dynamically linked executables. The userland of Linux simply isn't as stable time-wise as Windows, especially when the timescale is measured in decades.

As an example, the latest Atari Jaguar linker (aln) for Linux was released back in 1995. It's a proprietary, statically-linked 32-bit Linux a.out executable. To run this on a modern Linux system, you need to:

- Bump vm.mmap_min_addr from 65536 down to 4096, a privileged operation ;

- Use an a.out loader because the Linux kernel dropped support for a.out back in 2022 ;

- Possibly use qemu-user if your system doesn't support 32-bit x86.

That's the best-case scenario, because some of the old Atari Jaguar SDK Linux binaries are dynamically-linked a.out executables and you're basically stuck running ancient Linux kernels in a VM. It's at a point where someone at the AtariAge forums was seriously considering using my delinking black magic to port some of these old programs to modern Linux. It's quite telling when reverse-engineering an executable with Ghidra in order to export relocatable object files to relink (with some additional steps I won't get into) is even an option on the table.

Sure, given enough determination and piles of hacks you can probably forcefully run any old random Linux program on modern systems, but odds are that Windows (or Wine or ReactOS) will manage to run a 32-bit x86 PE program from thirty years ago with minimal compatibility tweaks. Linux (both distributions and to a lesser degree the kernel) simply don't care about that use-case, to the point where I'd be pleasantly surprised if anyone manages to run Tux the Penguin: A Quest for Herring as-is on a modern system.


> It's not just about dynamically linked executables. The userland of Linux simply isn't as stable time-wise as Windows, especially when the timescale is measured in decades.

That’s exactly what dynamically linked executables are: user land

> As an example, the latest Atari Jaguar linker (aln) for Linux was released back in 1995. It's a proprietary, statically-linked 32-bit Linux a.out executable.

That’s not a user land problem. That’s a CPU architecture problem. Windows solves this WOW64 which provides a compatibility layer for 32bit pointers et al.

There are 32bit compatibility layers for Linux too but they’re. It going to be going to help if you’re running an a.out file because it’s a completely different type of executable format (ie not equivalent to a 32bit statically compiled ELF).

Windows has a similar problem with COM files (the early DOS executable format). And lots of COM executables on Windows don’t work either. Windows solves this problem with emulation, which you can do on Linux too. The awkward part of Linux here is that it doesn’t ship those VMs as part of its base install, but why would it because almost no one is trying to run randomly downloaded 32bit a.out files.

To be clear, I’m not arguing that Linuxes backwards compatibility story is as good as Windows. It clearly isn’t. But the answer to that isn’t because Linux can’t be backwards compatible, it’s because Linux traditionally hasn’t needed to be. However all of the same tools Windows uses for it’s compatibility story are available to Linux for Linux executables too.


>> As an example, the latest Atari Jaguar linker (aln) for Linux was released back in 1995. It's a proprietary, statically-linked 32-bit Linux a.out executable.

> That’s not a user land problem. That’s a CPU architecture problem. Windows solves this WOW64 which provides a compatibility layer for 32bit pointers et al.

In this specific case, it really is a user-land problem.

I've went to the trouble of converting that specific executable into a statically linked 32-bit x86 ELF executable [1], to run as-is on modern x86 and x86_64 Linux systems. Besides rebasing it at a higher virtual address and writing about 10 lines of assembly to bridge the entrypoints, it's the same exact binary code as the original artifact. Unless you've specifically disabled or removed 32-bit x86 emulation, it'll run on a x86_64 kernel with no 32-bit userland compatibility layers installed.

Just for kicks, I've also converted it into a dynamically linked executable (with some glue to bridge glibc 1.xx and glib 2.xx) and even into a x86 PE executable that can run on Windows (using more glue and MSYS2) [2].

> Windows has a similar problem with COM files (the early DOS executable format). And lots of COM executables on Windows don’t work either. Windows solves this problem with emulation, which you can do on Linux too.

These cases aren't equivalent. COM and MZ are 16-bit executables for MS-DOS [3], NE is for 16-bit Windows ; all can be officially run without workarounds on 32-bit x86 Windows systems (NTVDM has admittedly spotty compatibility, but the point stands). Here, we're talking about 32-bit x86 code, so COM/MZ/NE does not apply here (to my knowledge there never has been 16-bit Linux programs anyways).

That Windows has 32-bit compatibility out of the box and that Linux distributions don't install 32-bit compatibility layers by default is one thing, but those on Linux only really apply to programs that at best share the same vintage as the host system (and at worst only work for the same distribution). Again, try running Tux the Penguin: A Quest for Herring as-is on a modern system (be it on a 32-bit or 64-bit installation, that part doesn't matter here), I'd gladly be proven wrong if it can be done without either a substantial rewrite+recompilation or egregious amounts of thunking a 2000's-era Linux userspace onto a 2020's-era one (no, a VM doesn't count, it has to run on the host).

[1] https://boricj.net/atari-jaguar-sdk/2023/12/18/part-3.html

[2] https://boricj.net/atari-jaguar-sdk/2024/01/02/part-5.html

[3] I know about 32-bit DOS extenders, but it's complicated enough as-is without bringing those into the mix.


> In this specific case, it really is a user-land problem.

a.out isnt even supported in new Linux kernels so how is that a user land problem? And you then repeated my point about how it’s not a user land problem by describing how it works as an ELF. ;)

> These cases aren't equivalent. COM and MZ are 16-bit executables for MS-DOS [3], NE is for 16-bit Windows ; all can be officially run without workarounds on 32-bit x86 Windows systems (NTVDM has admittedly spotty compatibility, but the point stands). Here, we're talking about 32-bit x86 code, so COM/MZ/NE does not apply here (to my knowledge there never has been 16-bit Linux programs anyways).

You’re not listening to what I’m saying.

COM and a.out are equivalent because they’re raw formats. Even on 32 bit NT systems COM required emulation.

The problem is the file formats are more akin to raw machine code than they are a modern container format.

So yeah, one is 16 and the other 32bit but the problem you’re describing is related to the file format being unforgiving for different CPU architectures without emulation; and in many cases, disregarding the user land entirely.

By your own admission, 32bit PEs and 32bit ELFs work perfectly fine on their respective Windows and Linux systems without any hacks.

The difference here is that Windows ships WOW64 as part of the base install whereas mainstream Linux distributions doesn’t ship 32bit libraries as part of their base install. That doesn’t mean that you need hacks for 32bit though. For example on Arch it’s literally just one line in pacman.conf that you uncomment.

My point was, if you wanted to ship a Linux distribution that supported random ELF binaries then you could. And package managers like Nix prove this fact.

The reason it’s harder on Linux isn’t because it requires hacks. It’s because Linux has a completely different design for installing applications and thus backwards compatibility with random ELFs isn’t generally worth the effort.

Also it’s really not fair to argue that a.out, a format that’s defined in the 70s and looong since deprecated across all unix-like systems is proof that Linux isn’t backwards compatible. ELF has been the primary file format for nearly 30 years on Linux now and a.out was only relatively recently fully removed from the kernel.

Whereas COM has been problematic on Windows for the entirety of NT, including Windows 2000 and XP.


>It’s on of the many reasons Windows base install is so much heavier than a typical Linux base install.

Is that a bad thing if it means a seamless experience for users? Storage is cheap.


I never suggested it was a bad thing. I was just explaining the differences.

However to answer your question:

Storage hasn’t always been cheap. So it used to be a bad thing. Theses days, as you rightly said, it’s less of an issue.

But if you do want to focus on present day then it’s worth noting that these days FOSS does ship a lot of dependencies as part of their releases. Either via Docker containers, Nix packages, or static binaries (eg Go, Rust, etc). And they do this precisely because the storage cost is worth the convenience.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: