3 ms·
> Instead, the proper way to address this situation would be to compile static binaries, that, by their very nature, become distribution agnostic. Thats only t
by hnlmorg 2y ago
> Instead, the proper way to address this situation would be to compile static binaries, that, by their very nature, become distribution agnostic.
Thats only true if you do not depend on glibc, which some statically compiled binaries still do. And even then, you’d have to rule out anything that requires newer sysalls or platforms that don’t offer stable ABI guarantees (Linux is actually the edge case here in that most kernels offer no guarantees).
It’s certainly doable though.
- arccy 2y agoit's not really static if you depend on glibc... things can still break, e.g. when compiled on too new glibc it fails to run on older versions.
- GoblinSlayer 2y agoI compile with glibc 2.17 and my programs run on all gnu systems.
- ptsneves 2y agoSetting up a machine or build system for older glibc is not trivial . If you know of any DISTRO which allows you to downgrade glibc out of the box please let me know. Keep in mind that if you go back enough you will also have trouble with kernel headers and compiler interactions. Even in yocto which is a build system that builds custom distributions from scratch does not have a great experience for different glibc versions than what is shipped. Have a look at the nightmare recipes for libc. On the other hand they do provide the basics of how to ship a custom libc loader across heterogeneous machines but it gets complicated fast and not something any non specialist can do in an hour. In my experience anybody saying to compile statically does not know about the libc limitations. When they find them they hand wave, I smile and say be my guest. By the way 2.17 is an appropriate version to target. RHEL6 much? :D
- dgrunwald 2y agoYou don't need a distro with ancient glibc; you can instead create a cross-compilation toolchain. We used https://crosstool-ng.github.io/docs/ https://crosstool-ng.github.io/docs/ to create a cross-compilation toolchain that runs on modern debian, but produces executables that only need glibc 2.17. The only downside is that you no longer can simply apt-get a library you need -- all dependencies shipped along with your application also need to be built with this cross-compiler.
- forrestthewoods 2y ago> Setting up a machine or build system for older glibc is not trivial . God, I hate glibc so much. It’s an absolutely terrible design from the 80s. It can and should be trivial to target any arbitrary version of glibc. The way Linux performs linking is so bad and so much worse than Windows. (Headers + thin import lib. Linking expecting a full and complete so is stupid and bad.) Zig solved this problem. It can trivially target any version of glibc and cross-compile. It’d be nice if the Linux community demanded this level of functionality from their toolchains. Alas. https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html https://andrewkelley.me/post/zig-cc-powerful-drop-in-replace...
- glandium 2y agoLinking does not expect a full and complete so. That's what it's currently fed, but it's not a requirement. You could just as well have "import libs" in ELF too.
- forrestthewoods 2y agoNeither GCC nor Clang produce "import libs" on Linux. The entire ecosystem is built around linking whatever full .so happen to be in the global search path. What Zig does is goes way way way out of it's way to compile import libs which contains all of the exported functions but the implementations are empty. So you aren't wrong. But the point is that the monumentally large Linux ecosystem does not work that way. Which is a real shame.
- 2y ago
- hnlmorg 2y ago> it's not really static if you depend on glibc Most operating systems don’t provide guarantees about ABI stability between versions, instead mandating that libc (or other user space APIs) are the intended interface to syscalls. Because if this, you can often come across statically compiled executables will still depend on glibc while inlining stuff like libpng. > if you depend on glibc... things can still break, e.g. when compiled on too new glibc it fails to run on older versions. That’s the point I was making ;)
- supriyo-biswas 2y agoThe glibc dependency can usually be eliminated through the same process of static compilation; the binaries I linked are also built this way with no dependencies on glibc, for example. > platforms that don’t offer stable ABI guarantees If we're talking about Windows, the Win32 ABI is considered stable, which would also suffice for what I'm looking for, which are portable binaries that can be run on almost any version of a system.
- rcxdude 2y agostatically linking against glibc does break some things (it's not an officially supported option because of that), though musl is an option and for most apps a reasonable replacement.
- lloeki 2y agoAt work we have this C++ that needs to be distributed as, in essence, a shared lib, and that needs to work with a lot of variability. So it has C++ and so needs a C++ stdlib. Dynamically linking is annoying so what if we statically link it? Oh but GNU's C++ stdlib wants glibc and has versioned BS and so even statically linking the C++ bits isn't ideal. And as mentioned statically linking glibc is a big no no. So: a) build a musl and install it in a prefix b) add a few bits (some headers and C runtime objects) and turn it into a sysroot c) build llvm's libc++ libunwind and a couple others, linking against that sysroot, and install it in the sysroot d) build our shared lib, statically linking against that sysroot The result is a shared lib that is self-contained except for the C stdlib, and any reference to the C stdlib has no GNUism nor glibc version. The trick is that musl is essentially a subset of glibc + there is no such thing as a musl-ism per musl's design tenets + the C ABI is stable enough. I don't recall us statically linking to musl - IIRC the trick is just to not have any GNUism at any level, in a way it also working in musl is kind of a happy side effect - but maybe I'm wrong. As a consequence it works on all glibc versions and musl as well, and is entirely independent of the system's preferred C++ stdlib. A requirement though is to load the shared library with RTLD_LOCAL (to not accidentally make internal symbols available to the outside) and RTLD_DEEPBIND (to not accidentally pick external symbols instead of internal ones)
- 2y ago
- tripflag 2y agoReplacing glibc with musl is usually unproblematic. That's what I did for my own portable toolbox which builds to a single self-extracting binary; https://github.com/9001/lxc https://github.com/9001/lxc