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

Easy static link everything.

I think you meant a GUI application that runs on a version of Linux older than yours.




I tried that with Rust, actually. My Manjaro was running a much newer version of Glibc than my server so I had to deal with that.

First I tried to get it to link to a different system library but no package manager is happy with multiple major versions of glibc.

Then I tried MUSL but it turns out the moment you enable MUSL several OpenSSL packages used in very common dependencies don't compile anymore. There was something about a custom OpenSSL path that I would need to specify and a cert file I'd need to package, but I gave up at that point.

The solution was to use a Docker image of an ancient version of Debian with an old version of glibc to build the file. I have no idea how you'd deal with this crap if your version of glibc is even older or if you don't have glibc, my conclusion was "I guess you can't use the usual HTTP crates then".

Oh, and the "just statically link everything" approach is also terrible for security patches because most developers don't release security patches with the same urgency as library developers do. GnuTLS had some pretty terrible problems a while back that were quickly resolved with an update but the most recent version of some binaries online are still vulnerable because the devs chose to statically link GnuTLS and abandoned the project a while back.

Libraries are an enormous pain point for Linux development and even static linking won't always be there to save you. This is one of the reasons some game developers choose to release a "Linux version" of their game by just packaging Proton/Wine with their executable and making sure their game performs well under the compatibility layer. All the different versions of all the different distributions and all the different flavours are impossible to keep up with.

Linux devs have chosen to ship entire Linux core libraries with their applications in the form of AppImage/Flatpak/Snap/Docker to solve this problem. If static linking solved all problems, Docker wouldn't have taken off like it did.


"Statically link or bundle everything" is how most Windows apps deal with this tho. So if we're comparing Windows and Linux, and saying that Linux packaging is worse, this method can't just be dismissed on security grounds.


Windows developers tend to stuff directories full of DLLs if they need to ship dependencies, they're not statically linked per se.

Regardless, it's incredibly complicated to compare linking behaviour between Windows and Linux. Windows has tons of components built into the API (and which is maintained by Microsoft) which you'd need an external dependency for in Linux. Microsoft provides interfaces for things like XML processing, TLS connections, file system management, sound libraries, video libraries, rendering engines, scripting engines and more. If there's a vulnerability in WinHTTP, Microsoft will patch it; if you statically link curl, you'll have to fix it yourself.

Of course many open source developers will statically link binaries because that way they don't have to write platform specific code themselves, but they only need all those dependencies because your average distro is pretty bare bones if you strip it to its core components. If you write cod Linux, you're not even getting a GUI by your base platform, you'll have to provide your own bindings for either X11 or Wayland!

Most third party Windows software I run is some application code and maybe a few proprietary DLLs that the software authors bought. Sometimes those DLLs are even just reusable components from the vendor themselves. Only when I install cross compiled Linux software do I really see crazy stuff like a full copy of a Linux file system hidden somewhere in a Program Files folder (GTK+ really likes to do that) or a copy of a modified dotnet runtime (some Unity games).

The big exception to the rule, of course, is video games, but even those seem to include fewer and fewer external components.

Development becomes a lot easier when you can just assume that Microsoft will maintain and fix giant frameworks like the .NET Framework and the Visual C++ runtime (basically libc for Windows) for you. Microsoft even solved the problem of running multiple versions of their C runtime on the same machine through some tricky hard linking to get the right dependencies in the right place. As a result, most Windows executables I find in the wild are actually linked dynamically despite the lack of a library management system.


Hence "... or bundle everything". But what difference does it make from the security perspective? If the app ships its own copy of the DLL, it still needs to do security updates for it - the OS won't.

As far as the OS offering more - it's true, but not to the extent you describe. For example, Windows does offer UI (Win32), but most apps use a third-party toolkit on top of that. Windows does offer MSXML, but it's so dated you'd be hard-pressed to find anything written in the past decade that uses it. And so on, and so forth. I just went and did a search for Qt*.DLL in my Program Files, and it looks like there's a dozen apps that bundle it, including even Microsoft's own OneDrive (which has a full set including QML!).

Even with .NET, the most recent version bundled with Windows is .NET Framework 4.8, which is already legacy by this point - if you want .NET 5+, the standard approach is to package it with your app.

And then there's Electron, which is probably the most popular framework for new desktop apps on any platform including Windows - and it is, of course, bundled.

"Some application code and maybe a few proprietary DLLs" is how things were back in 00s, but it hasn't been true for a while now.


.NET Framework 4.8 will start being legacy, when Forms and WPF finally work end to end on Core runtime.

Heck the designer still has issues to render most stuff on .NET 6.


> Windows developers tend to stuff directories full of DLLs if they need to ship dependencies, they're not statically linked per se.

I assure you, there is plenty static going on in Windows land.


Statically link everything? Including glibc?


When trying to statically link everything, glibc is not as much a problem as GPU drivers are if you want binaries that work on more than one system


> Including glibc?

Any reasonable person doing this would use Musl of course.


And then you discover your program can't resolve hostnames because "DNS responses shouldn't be that big".


But honestly, they really shouldn't.


Can you explain how musl is related to this DNS resolving problem?



Trick question: glibc doesn't support that.

Trying to statically link with glibc is a fool's errand.


glibc doesn't support static linking, but you can fully static link with another libc if that is what you wanted to do.

Not that it is needed for forward-compatible Linux binaries since newer glibc versions are backwards compatible so dynamically linking the oldest one you want to support works fine. Would be nice if glibc/gcc supported targetting older versions directly without having to have an older copy installed but that is a convenience issue.


AppImage is sufficient.


nope, it still requires at least the glibc version that the appimage was compiled against. snaps, flatpaks nor appimage solve the long-standing glibc versioning issue that plagues portable Linux binaries. the closest I've seen to fixing this issue is https://github.com/wheybags/glibc_version_header


> the closest I've seen to fixing this issue is https://github.com/wheybags/glibc_version_header

Or just compile against an older glibc version. Plenty of tools to setup sysroots for that, e.g. https://wiki.gentoo.org/wiki/Crossdev




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: