[HN Gopher] The Holy Grail of Linux Binary Compatibility: Musl a...
___________________________________________________________________
The Holy Grail of Linux Binary Compatibility: Musl and Dlopen
Author : Splizard
Score : 201 points
Date : 2026-01-26 07:41 UTC (15 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| einpoklum wrote:
| This seems interesting even regardless of go. Is it realistic to
| create an executable which would work on very different kinds of
| Linux distros? e.g. 32-bit and 64-bit? Or maybe some general
| framework/library for building an arbitrary program at least for
| "any libc"?
| quesomaster9000 wrote:
| Cosmopolitan goes one further: [binaries] that runs natively on
| Linux + Mac + Windows + FreeBSD + OpenBSD + NetBSD + BIOS on
| AMD64 and ARM64
|
| https://justine.lol/cosmopolitan/
| oguz-ismail2 wrote:
| >Linux
|
| if you configure binfmt_misc
|
| >Windows
|
| if you disable Windows Defender
|
| >OpenBSD
|
| only older versions
| account42 wrote:
| Yeah while APE is a technically impressive trick, these
| issues far outweigh the minor convenience of having a
| single binary.
|
| For most cases, a single Windows exe that targets the
| oldest version you want to support plus a single Glibc
| binary that dynamically links against the oldest version
| you want to support and so on is still the best option.
| yjftsjthsd-h wrote:
| >> Linux
|
| > if you configure binfmt_misc
|
| I don't think that's a requirement, it'll just fall back to
| the shell script bootstrap without it.
| oguz-ismail2 wrote:
| On some distros, yes. On others it'll fire up Wine for
| whatever reason
| yjftsjthsd-h wrote:
| Okay, yes, if you configure binfmt_misc for WINE and not
| APE then PE-compatible binaries will get run with WINE
| and not APE. That feels unfair.
| oguz-ismail2 wrote:
| >if you configure binfmt_misc for WINE
|
| It came preconfigured on Ubuntu 20.04 and 22.04, don't
| know about newer versions.
| dontdoxxme wrote:
| Clearly a joke if it uses the .lol tld.
| account42 wrote:
| It's his personal website lol.
| hyperbolablabla wrote:
| Justine identifies as a woman.
| hofrogs wrote:
| "identifies as" is an unnecessarily dismissive choice of
| words. She _is_ a woman.
| hyperbolablabla wrote:
| My statement was a fact, and in my opinion not
| politically loaded, yet respectful to Justine. I chose my
| words carefully.
| sambuccid wrote:
| Appimage exists that packs linux applications into a single
| executable file that you just download and open. It works on
| most linux distros
| greyw wrote:
| I vaguely remember that Appimage-based programs would fail
| for me because of fuse and glibc symbol version
| incompatibilties.
|
| Gave up them afterwards. If I need to tweak dependencies
| might as well deal with the packet manager of my distro.
| iberator wrote:
| Yup. Just compile it as static executable. Static binaries are
| very undervalued imo.
| flohofwoe wrote:
| The "just" is doing a lot of heavylifting here (as detailed
| in the article), especially for anything that's not a trivial
| cmdline tool.
| qznc wrote:
| Ack. I went down that rabbit hole to "just" build a static
| Python: https://beza1e1.tuxen.de/python_bazel.html
| Xraider72 wrote:
| In my experience it seems to be an issue caused by
| optimizations in legacy code that relied on dlopen to
| implement a plugin system, or help with startup, since you
| could lazy load said plugins on demand and start faster.
|
| If you forego the requirement of a runtime plugin system,
| is there anything realistically preventing greenfield
| projects from just being fully statically linked, assuming
| their dependencies dont rely on dlopen ?
| flohofwoe wrote:
| It becomes tricky when you need to use system DLLs like
| X11 or GL/Vulkan (so you need to use the 'hacks'
| described in the article to work around that) - the
| problem is that those system DLLs then bring a
| dynamically linked glibc into the process, so suddenly
| you have two C stdlibs running side by side and the
| question is whether this works just fine or causes subtle
| breakage under the hood (e.g. the reason why MUSL doesn't
| implement dlopen).
|
| E.g. in my experience: command line tools are fine to
| link statically with MUSL, but as soon as you need a
| window and 3D rendering it's not worth the hassle.
| account42 wrote:
| X11 actually has a stable wire protocol so you don't
| strictly need any dynamic libraries for that - it's just
| that no one bothers because if you want X11 then you most
| likely also want GPU access where you do need to load
| hardware-specific libraries.
| account42 wrote:
| As TFA points out at the beginning, it's not so simple if you
| want to use the GPU.
| pjmlp wrote:
| We had a time when static binaries where pretty much the only
| thing we had available.
|
| Here is an idea, lets go back to pure UNIX distros using
| static binaries with OS IPC for any kind of application
| dynamism, I bet it will work out great, after all it did for
| several years.
|
| Got to put that RAM to use.
| jacquesm wrote:
| I've been static linking my executables for years. The
| downside, that you might end up with an outdated library,
| is no match for the upsite: just take the binary and run
| it. As long as you're the only user of the system and the
| code is your own you're going to be just fine.
| account42 wrote:
| I don't think dynamic libraries fail at "utilizing" any
| available RAM.
| pjmlp wrote:
| Think of any program that uses dynamic libraries as
| extension mechanism, and now replace it with standard
| UNIX processes, each using any form of UNIX IPC to talk
| with the host process instead.
| account42 wrote:
| In theory there might be a different RAM usage with the
| two approaches. In practice there is not.
| pjmlp wrote:
| And your measurements are available where?
| flohofwoe wrote:
| The thing with static linking is that it enables aggressive
| dead code elimination (e.g. DLL are a hard optimization
| barrier).
|
| Even with multiple processes sharing the same DLL I would
| be surprised if the alternative of those processes only
| containing the code they actually need would increase RAM
| usage dramatically, especially since most processes that
| run in the background on a typical Linux system wouldn't
| event even need to go through glibc but could talk directly
| to the syscall interface.
|
| DLLs are fine as operating system interface as long as they
| are stable (e.g. Windows does it right, glibc doesn't). But
| apart from operating system interfaces and plugins,
| overusing dynamic linking just doesn't make a lot of sense
| (like on most Linux systems with their package managers).
| pjmlp wrote:
| While at the same time it prevents extending
| applications, the alternatives being multiple processes
| using OS IPC, all of them much slower and heavier on
| resources than an indirect call on a dynamic library.
|
| We started there in computing history, and outside Linux
| where this desire to go to the past prevails, moved on to
| better ways including on other UNIX systems.
| amelius wrote:
| Is there a tool that takes an executable, collects all the
| required .so files and produces either a static executable, or a
| package that runs everywhere?
| mdavid626 wrote:
| You can "package" all .so files you need into one file, there
| are many tools which do this (like a zip file).
|
| But you can't take .so files and make one "static" binary out
| of them.
| fc417fc802 wrote:
| Well not a static binary in the sense that's commonly meant
| when speaking about static linking. But you can pack .so
| files into the executable as binary data and then dlopen the
| relevant memory ranges.
| mdavid626 wrote:
| Yes, that's true.
|
| But I'm always a bit sceptical about such approaches. They
| are not universal. You still need glibc/musl to be the same
| on the target system. Also, if you compile againt new glibc
| version, but try to run on old glibc version, it might not
| work.
|
| These are just strange and confusing from the end users'
| perspective.
| toast0 wrote:
| > But I'm always a bit sceptical about such approaches.
| They are not universal. You still need glibc/musl to be
| the same on the target system. Also, if you compile
| againt new glibc version, but try to run on old glibc
| version, it might not work.
|
| Why would you include most of your dynamic libraries but
| not your libc?
|
| You could still run into problems if you (or your
| libraries) want to use syscalls that weren't available on
| older kernels or whatever.
| mdavid626 wrote:
| You can include it, but
|
| - either you use chroot, proot or similar to make /lib
| path contain your executable's loader
|
| - or you hardcode different loader path into your
| executable
|
| Both are difficult for an end user.
| toast0 wrote:
| This isn't that hard (that's not to say this is easy, it
| is tricky). Your executable should be a statically linked
| stub loader with an awful lot of data, the stub loader
| dynamically links your real executable (and libraries,
| including libc) from the data and runs it.
| fc417fc802 wrote:
| To add to this, in case of any remaining confusion. You
| can implement your own execve in userspace. [0] But the
| kernel's execve is a piece of machinery that invokes the
| loader so obviously it follows that you're free to make
| any changes you'd like to the overall process.
|
| Bonus points if you add compression or encryption and
| manage to trip a virus scanner or three. [1]
|
| [0] https://grugq.github.io/docs/ul_exec.txt
|
| [1] https://blackhat.com/presentations/bh-
| usa-07/Yason/Whitepape...
| geocar wrote:
| > But you can't take .so files and make one "static" binary
| out of them.
|
| Yes you can!
|
| This is more-or-less what unexec does
|
| - https://news.ycombinator.com/item?id=21394916
|
| For some reason nobody seems to like this sorcery, probably
| because it combines the worst of all worlds.
|
| But there's almost[1] nothing special about what the dynamic
| linker is doing to get those .so files into memory that it
| can't arrange them in one big file ahead of time!
|
| [1]: ASLR would be one of those things...
| mdavid626 wrote:
| What if the library you use calls dlopen later? That'll
| fail.
|
| There is no universal, working way to do it. Only some
| hacks which work in some special cases.
| geocar wrote:
| > What if the library you use calls dlopen later? That'll
| fail.
|
| Nonsense. xemacs could absolutely call dlopen.
|
| > There is no universal, working way to do it. Only some
| hacks which work in some special cases.
|
| So you say, but I remember not too long ago you weren't
| even aware it was possible, and you clearly didn't check
| one of the most prominent users of this technique, so
| maybe you should also explain why I or anyone else should
| give a fuck about what you think is a "hack"?
| TheDong wrote:
| There are things like this.
|
| The things I know of and can think of off the top of my head
| are:
|
| 1. appimage https://appimage.org/
|
| 2. nix-bundle https://github.com/nix-community/nix-bundle
|
| 3. guix via guix pack
|
| 4. A small collection of random small projects hardly anyone
| uses for docker to do this (i.e.
| https://github.com/NilsIrl/dockerc )
|
| 5. A docker image (a package that runs everywhere, assuming a
| docker runtime is available)
|
| 6. https://flatpak.org/
|
| 7. https://en.wikipedia.org/wiki/Snap_(software)
|
| AppImage is the closest to what you want I think.
| amelius wrote:
| AppImage looks like what I need, thanks.
|
| I wonder though, if I package say a .so file from nVidia, is
| that allowed by the license?
| c0balt wrote:
| Depends on the license and the specific piece of software.
| Redistribution of commercial software is may be restricted
| or require explicit approval.
|
| You generally still also have to abide by license
| obligations for OSS too, e. G., GPL.
|
| To be specific for the exampls, Nvidia has historically
| been quite restrictive (only on approval) here. Firmware
| has only recently been opened up a bit and drivers continue
| to be an issue iirc.
| mdavid626 wrote:
| Don't forget - AppImage won't work if you package something
| with glibc, but run on musl/uclibc.
| direwolf20 wrote:
| No, that's a copyright violation, and it won't run on AMD
| or Intel GPUs, or kernels with a different Nvidia driver
| version.
| amelius wrote:
| But this ruins the entire idea of packaging software in a
| self-contained way, at least for a large class of
| programs.
|
| It makes me wonder, does the OS still take its job of
| hardware abstraction seriously these days?
| holowoodman wrote:
| The OS does. Nvidia doesn't.
| direwolf20 wrote:
| Does Nvidia not support OpenGL?
| holowoodman wrote:
| Not really. Nvidia-OpenGL is incompatible to all existing
| OS OpenGL interfaces, so you need to ship a separate
| libGL.so if you want to run on Nvidia. In some cases you
| even need separate binaries, because if you dynamically
| link against Nvidia's libGL.so, it won't run with any
| other libGL.so. Sometimes also vice versa.
| direwolf20 wrote:
| Does AMD use a statically linked OpenGL?
| holowoodman wrote:
| AMD uses the dynamically linked system libGL.so, usually
| Mesa.
| direwolf20 wrote:
| So you still need dynamic linking to load the right
| driver for your graphics card.
| holowoodman wrote:
| Most stuff like that uses some kind of "icd" mechanism
| that does 'dlopen' on the vendor-specific parts of the
| library. Afaik neither OpenGL nor Vulkan nor OpenCL are
| usable without at least dlopen, if not full dynamic
| linking.
| direwolf20 wrote:
| It does, and one way it does that is by dynamically
| loading the right driver code for your hardware.
| maccard wrote:
| That's a licensing problem not a packaging problem. A DLL
| is a DLL - only thing that changes is whether you're
| allowed redistribute it
| ValdikSS wrote:
| AppImage is _not_ what you need. It 's just an executable
| wrapper for the archive. To make the software cross-distro,
| you need to compile it manually on an old distro with old
| glibc, make sure all the dependencies are there, and so on.
|
| https://docs.appimage.org/reference/best-
| practices.html#bina...
|
| There are several automation tools to make AppImages, but
| they won't magically allow you to compile on the latest
| Fedora and expect your executable to work on Debian Stable.
| It's still require quite a lot of manual labor.
| ndiddy wrote:
| Yeah a lot of Appimage developers make assumptions about
| what their systems have as well (i.e. "if I depend on
| something that is installed by default on Ubuntu desktop
| then it's fine to leave out"). For example, a while ago I
| installed an Appimage GUI program on a headless server
| that I wanted to use via X11 forwarding. I ended up
| having to manually install a bunch of random packages
| (GTK stuff, fonts, etc) to get it to run. I see Appimage
| as basically the same as distributing Linux binaries via
| .tar.gz archives, except everything's in a single file.
| ValdikSS wrote:
| >I wonder though, if I package say a .so file from nVidia,
| is that allowed by the license?
|
| It won't work: drivers usually require exact (or more-or-
| less the same) kernel module version. That's why you need
| to explicitly exclude graphics libraries from being
| packaged into AppImage. This make it non-runnable on musl
| if you're trying to run it on glibc.
|
| https://github.com/Zaraka/pkg2appimage/blob/master/excludel
| i...
| saidinesh5 wrote:
| Typically appimage packaging excludes the .so files that
| are expected to be provided by the base distro.
|
| Any .so from nvidia is supposed to be one of those things.
| Because it also depends on the drivers etc.. provided by
| nvidia.
|
| Also on a side note, a lot of .so files also depends on
| other files in /usr/share , /etc etc...
|
| I recommend using an AppImage only for the happy path
| application frameworks they support (eg. Qt, Electron
| etc...). Otherwise you'd have to manually verify all the
| libraries you're bundling will work on your user's distros.
| gilli wrote:
| I wish AppImage was slightly more user friendly and did not
| require the user to specifically make it executable.
| VadimPR wrote:
| We fix this issue by distributing ours in a tar file with
| the executable bit set. Linux novices can just double click
| on the tar to exact it and double click again on the actual
| appimage.
|
| Been doing it this way for years now, so it's well battle
| tested.
| account42 wrote:
| That kind of defeats the point of an AppImage though -
| you could just as well have a tar archive with a c
| classic collection of binaries + optional launcher
| script.
| a022311 wrote:
| It should be noted that AppImages tend to be noticeably
| slower at runtime than other packaging methods and also very
| big for typical systems which include most libraries. They're
| good as a "compile once, run everywhere" approach but you're
| really accommodating edge cases here.
|
| A "works in most cases" build should also be available for
| that that it would benefit. And if you can, why not provide
| specialized packages for the edge cases?
|
| Of course, don't take my advice as-is, you should always
| thoroughly benchmark your software on real systems and choose
| the tradeoffs you're willing to make.
| saghm wrote:
| IMO one of the best features of AppImage is that it makes
| it easy to extract without needing external tools. It's
| usually pretty easy for me to look at an AppImage and write
| a PKGBUILD to make a native Arch package; the format
| already encodes what things need to be installed where, so
| it's only a question of whether the libraries it contains
| are the same versions of what I can pull in as dependencies
| (either from the main repos or the AUR). If they are, my
| job is basically already done, and if they aren't, I can
| either choose to include them in the package itself
| assuming I don't have anything conflicting (which is fine
| for local use even if it's not something that's usually
| tolerated when publishing a package) or stick with using
| the AppImage.
| a022311 wrote:
| I agree. I've seen quite a few AUR packages built that
| way and I'm using a few myself too. The end user
| shouldn't be expected to do this though! :D
| badsectoracula wrote:
| > It should be noted that AppImages tend to be noticeably
| slower at runtime than other packaging methods
|
| 'Noticeably slower' at what? I've run, e.g. xemu (original
| xbox emulator) as both manually built from source and via
| AppImage-based released and i never noticed any difference
| in performance. Same with other AppImage-based apps i've
| been using.
|
| Do you refer to launching the app or something like that?
| TBH i cannot think of any other way an AppImage would be
| "slower".
|
| Also from my experience, applications released using
| AppImages has been the most consistent by far at "just
| working" on my distro.
| aa-jv wrote:
| AppImage comes close to fulfilling this need:
|
| https://appimage.github.io/appimagetool/
|
| Myself, I've committed to using Lua for all my cross-platform
| development needs, and in that regard I find luastatic very,
| very useful ..
| formerly_proven wrote:
| I don't think you can link shared objects into a static binary
| because you'd have to patch all instances where the code reads
| the PLT/GOT, but this can be arbitrarily mangled by the
| optimizer, and turn them back into relocations for the linker
| to then resolve them.
|
| You can change the rpath though, which is sort of like an
| LD_LIBRARY_PATH baked into the object, which makes it
| relatively easy to bundle everything but libc with your binary.
|
| edit: Mild correction, there is this:
| https://sourceforge.net/projects/statifier/ But the way this
| works is that it has the dynamic linker load everything
| (without ASLR / in a compact layout, presumably) and then dumps
| an image of the process. Everything else is just increasingly
| fancy ways of copying shared objects around and making ld.so
| prefer the bundled libraries.
| fieu wrote:
| Ermine: https://www.magicermine.com/
|
| It works surprisingly well but their pricing is hidden and last
| time I contacted them as a student it was upwards of $350/year
| secure wrote:
| https://github.com/gokrazy/freeze is a minimal take on this
| alas44 wrote:
| There is this project "actually portable
| executable"/cosmopolitan libc
| https://github.com/jart/cosmopolitan that allows a compile once
| execute anywhere style type of C++ binary
| lizknope wrote:
| 15-30 years ago I managed a lot of commercial chip design EDA
| software that ran on Solaris and Linux. We had wrapper shell
| scripts for so many programs that used LD_LIBRARY_PATH and
| LD_PRELOAD to point to the specific versions of various
| libraries that each program needed. I used "ldd" which prints
| out the shared libraries a program uses.
| mkoubaa wrote:
| Sounds painful. Better to distrib a separate bundle per
| platform and use RPATH
| ValdikSS wrote:
| It you know what you're doing and scrupulous enough, you can
| package the software in a way that it works 25 years later.
|
| https://xcancel.com/ValdikSS/status/1843044963443253678
| ryan-c wrote:
| (not an endorsement, I do not use it, but I know of it)
|
| https://www.magicermine.com/
| saghm wrote:
| I don't think it's as simple as "run this one thing to package
| it", so if the process rather than the format is what you're
| looking for, this won't work, but that sounds a lot like how
| AppImages work from the user perspective. My understanding is
| that an AppImage is basically a static binary paired with a
| small filesystem image containing the "root" for the
| application (including the expected libraries under /usr/lib or
| wherever they belong). I don't line everything about the
| format, but overall it feels a lot less prescriptive than other
| "universal" packages like flatpak or snap, and the fact that
| you can easily extract it and pick out the pieces you want to
| repackage without needing any external tools (there are built-
| in flags on the binary like --appimage-extract) in helps a lot.
| jcalvinowens wrote:
| mkdir chroot cd chroot for lib in $(ldd
| ${executable} | grep -oE '/\S+'); do tgt="$(dirname
| ${lib})" mkdir -p .${tgt} cp ${lib} .${tgt}
| done mkdir -p .$(dirname ${executable}) cp
| ${executable} .${executable} tar cf ../chroot-run-
| anywhere.tgz .
| saidinesh5 wrote:
| You're supposed to do this recursively for all the libs no?
|
| Eg. Your App might just depend on libqt5gui.so but that
| libqt5gui.so might depend on some libxml etc...
|
| Not to mention all the files from /usr/share etc... That your
| application might indirectly depend on.
| Conscat wrote:
| Someone already mentioned AppImage, but I'd like to draw
| attention to this alternate implementation that executes as a
| POSIX shell script, making it possible to dynamic dispatch
| different programs on different architectures. e.g. a fat
| binary for ARM and x64.
|
| https://github.com/mgord9518/shappimage
| sekh60 wrote:
| So autotools but for execution instead of compilation?
| fdgdd wrote:
| Exodus (https://github.com/intoli/exodus) used to be good for
| this but is giving me a Python error these days.
| Meneth wrote:
| That seems mostly useful for proprietary programs. I don't like
| it.
| seba_dos1 wrote:
| Yeah, in my 20 years of using and developing on GNU/Linux the
| only binary compatibility issues I experienced that I can think
| of now were related to either Adobe Flash, Adobe Reader or
| games.
|
| Adobe stuff is of the kind that you'd prefer to not exist at
| all rather than have it fixed (and today you largely can
| pretend that it never existed already), and the situation for
| games has been pretty much fixed by Steam runtimes.
|
| It's fine that some people care about it and some solutions are
| really clever, but it just doesn't seem to be an actual issue
| you stumble on in practice much.
| whizzter wrote:
| The solution to games is to load Windows games instead of
| Linux binaries.
|
| Basically the way for the year of the Linux desktop is to
| become Windows.
| seba_dos1 wrote:
| These days Linux binaries usually work fine, even older
| ones, and when they don't the reason is that they often
| don't get the same attention as their Windows counterparts.
| paddim8 wrote:
| Probably because your distro purposefully keeps software out
| of date because it is too fragile otherwise. I don't think
| that is reasonable at all for desktop use.
| seba_dos1 wrote:
| Arch?...
| juliangmp wrote:
| Why? Foss software also benefits from less dependency hell.
| breezykoi wrote:
| For distro-packaged FOSS, binary compatibility isn't really a
| problem. Distributions like Debian already resolve
| dependencies by building from source and keeping a coherent
| set of libraries. Security fixes and updates propagate
| naturally.
|
| Binary compatibility solutions mostly target cases where
| rebuilding isn't possible, typically closed source software.
| Freezing and bundling software dependencies ultimately
| creates dependency hell rather than avoiding it.
| account42 wrote:
| There is however also the long tail of open source software
| that isn't packaged for your favorite distribution.
| breezykoi wrote:
| That is very true. But because it is open source, one can
| request for packaging, contribute a package, use a third-
| party repository, or build it from source when needed.
| koffiezet wrote:
| It however shifts a lot of the complexity of building the
| application to the distro maintainer, or a software
| maintainer has to prioritize for which distribution they
| choose to build and maintain a package, because supporting
| them all is a nightmare and an ever shifting moving target.
| And it's not just a distribution problem, it's even a
| distribution version/release problem.
|
| Look at the hoops you sometimes have to jump through or
| hacks you have to apply to make something work on Nix, just
| because there is no standardization or build processes
| assume library locations etc. And if you then raise an
| issue with the software maintainer - the response is often
| "but we don't support Nix". And if they're not Nix/Nixos
| users, can you blame them?
|
| If you've ever had to compile a modern/recent software
| package for an old distro (I've had to do this for old RH
| distro's on servers which due to regulations could not be
| upgraded) - you're in a world of pain. And both distro and
| software maintainers will say "not my problem, we don't
| support this" - and I fully understand their stance on
| that, because it is far from straight forward, and only
| serves a limited audience.
| Faelian2 wrote:
| I did wrote a small open-source tool in Rust. And I too did
| encounter that kind of issue when I did start to build a .deb.
|
| Honestly, it was the kind of bug that is not fun to fix,
| because it's really about dependency, and not some fun code
| issue. There is no point in making our life harder with this to
| gatekeep proprietary software to run on our platform.
| athrowaway3z wrote:
| I'd never heard of detour. That's a pretty cool hack.
| ckbkr10 wrote:
| they were prominent in game hacking 2005ish windows
|
| made hooking into game code much easier than before
| sidewndr46 wrote:
| Aren't all DLLs on the Windows platform compiled with an
| unusual instruction at the start of each function? This makes
| it possible to somehow hot patch the DLL after it is already
| in memory
| leeter wrote:
| I believe you're thinking of the x86 Hotpatching hook[1],
| which doesn't exist on x86-64[2] (in the same form, it uses
| a x86-64 safe one).
|
| [1] https://devblogs.microsoft.com/oldnewthing/20110921-00/
| ?p=95...
|
| [2] https://devblogs.microsoft.com/oldnewthing/20221109-00/
| ?p=10...
| sidewndr46 wrote:
| yes, that's it. Thanks for clarifying
| mgaunard wrote:
| It's funny how people insist on wanting to link everything
| statically when shared libraries were specifically designed to
| have a better alternative.
|
| Even worse is containers, which has the disadvantage of both.
| vv_ wrote:
| It's easier to distribute software fully self-contained, if you
| ignore the pain of statically linking everything together :)
| fc417fc802 wrote:
| Dynamic linking exists to make a specific set of tradeoffs.
| Neither better nor worse than static linking in the general
| sense.
| arghwhat wrote:
| Dynamic libraries have been frowned upon since their inception
| as being a terrible solution to a non-existent problem,
| generally amplifying binary sizes and harming performance. Some
| fun quotes of quite notable characters on the matter here:
| https://harmful.cat-v.org/software/dynamic-linking/
|
| In practice, a statically linked system is often smaller than a
| meticulously dynamically linked one - while there are many
| copies of common routines, programs only contain tightly
| packed, specifically optimized and sometimes inlined versions
| of the symbols they use. The space and performance gain per
| program is quite significant.
|
| Modern apps and containers are another issue entirely - linking
| doesn't help if your issue is gigabytes of graphical assets or
| using a container base image that includes the entire world.
| holowoodman wrote:
| Statically linked binaries are a huge security problem, as
| are containers, for the same reason. Vendors are too slow to
| patch.
|
| When dynamically linking against shared OS libraries, Updates
| are far quicker and easier.
|
| And as for the size advantage, just look at a typical Golang
| or Haskell program. Statically linked, two-digit megabytes,
| larger than my libc...
| zbentley wrote:
| I've heard this many times, and while there might be data
| out there in support of it, I've never seen that, and my
| anecdotal experience is more complicated.
|
| In the most security-forward roles I've worked in, the
| vast, _vast_ majority of vulnerabilities identified in
| static binaries, Docker images, Flatpaks, Snaps, and VM
| appliance images fell into these categories:
|
| 1. The vendor of a given piece of software based their
| container image on an outdated version of e.g. Debian, and
| the vulnerabilities were coming from that, not the software
| I cared about. This seems like it supports your point, but
| consider: the overwhelming majority of these required a
| distro upgrade, rather than a point dependency upgrade of
| e.g. libcurl or whatnot, to patch the vulnerabilities.
| Countless times, I took a normal long-lived Debian test VM
| and tried to upgrade it to the patched version and then
| install whatever piece of software I was running in a
| docker image, and had the upgrade fail in some way
| (everything from the less-common "doesn't boot" to the
| very-common "software I wanted didn't have a distribution
| on its website for the very latest Debian yet, so I was
| back to hand-building it with all of the dependencies and
| accumulated cruft that entails").
|
| 2. Vulnerabilities that were unpatched or _barely_ patched
| upstream (as in: a patch had merged but hadn 't been baked
| into released artifacts yet--this applied equally to vulns
| in things I used directly, and vulns in their underlying
| OSes).
|
| 3. _Massive_ quantities of vulnerabilities reported in
| "static" languages' standard libraries. Golang is
| particularly bad here, both because they habitually over-
| weight the severity of their CVEs and because most of the
| stdlib is packaged with each Golang binary (at least as far
| as SBOM scanners are concerned).
|
| That puts me somewhat between a rock and a hard place. A
| dynamic-link-everything world with e.g. a "libgolang"
| versioned separately from apps would address the 3rd item
| in that list, but would make the 1st item worse. "Updates
| are far quicker and easier" is something of a fantasy in
| the realm of mainstream Linux distros (or copies of the
| userlands of those distros packaged into container images);
| it's certainly easier to mechanically _perform_ an update
| of dependency components of a distro, but whether or not it
| actually _works_ is another question.
|
| And I'm not coming at this from a pro-container-all-the-
| things background. I was a Linux sysadmin long before all
| this stuff got popular, and it used to be a _little_ easier
| to do patch cycles and point updates before container
| /immutable-image-of-userland systems established the
| convention of depending on extremely specific
| characteristics of a specific revision of a distro. But it
| was never truly easy, and isn't easy today.
| adrian_b wrote:
| This is the theory, but not the practice.
|
| In decades of using and managing many kinds of computers I
| have seen only a handful of dynamic libraries for whom
| security updates have been useful, e.g. OpenSSL.
|
| On the other hands, I have seen countless problems caused
| by updates of dynamic libraries that have broken various
| applications, not only on Linux, but even on Windows and
| even for Microsoft products, such as Visual Studio.
|
| I have also seen a lot of space and time wasted by the
| necessity of having installed in the same system, by using
| various hacks, a great number of versions of the same
| dynamic library, in order to satisfy the conflicting
| requirements of various applications. I have also seen
| systems bricked by a faulty update of glibc, if they did
| not have any statically-linked rescue programs.
|
| On Windows such problems are much less frequent only
| because a great number of applications bundle with the
| them, in their own directory, the desired versions of
| various dynamic libraries, and Windows is happy to load
| those libraries. On UNIX derivatives, this usually does not
| work as the dynamic linker searches only standard places
| for libraries.
|
| Therefore, in my opinion static linking should always be
| the default, especially for something like the standard C
| library. Dynamic linking shall be reserved for some very
| special libraries, where there are strong arguments that
| this should be beneficial, i.e. that there really exists a
| need to upgrade the library without upgrading the main
| executable.
|
| Golang is probably an anomaly. C-based programs are rarely
| much bigger when statically linked than when dynamically
| linked. Only using "printf" is typically implemented in
| such a way that it links a lot into any statically-linked
| program, so the C standard libraries intended for embedded
| computers typically have some special lightweight "printf"
| versions, to avoid this overhead.
| toast0 wrote:
| > In decades of using and managing many kinds of
| computers I have seen only a handful of dynamic libraries
| for whom security updates have been useful, e.g. OpenSSL.
|
| > On the other hands, I have seen countless problems
| caused by updates of dynamic libraries that have broken
| various applications,
|
| OpenSSL is a good example of both useful and problematic
| updates. The number of updates that fixed a critical
| security problem but needed application changes to work
| was pretty high.
| ranger_danger wrote:
| Would be nice if there was a binary format where you could
| easily swap out static objects for updated ones
| rlpb wrote:
| Imagine a fully statically linked version of Debian. What
| happens when there's a security update in a commonly used
| library? Am I supposed to redownload a rebuild of basically
| the entire distro every time this happens, or else what?
| electroly wrote:
| Steel-manning the idea, perhaps they would ship object
| files (.o/.a) and the apt-get equivalent would link the
| system? I believe this arrangement was common in the days
| before dynamic linking. You don't have to redownload
| everything, but you do have to relink everything.
| holowoodman wrote:
| But if I have to relink everything, I need all the
| makefiles, linker scripts and source code structure. I
| might as well compile it outright. On the other hand, I
| might as well just link it whenever I run it, like,
| dynamically ;)
| rlpb wrote:
| And then how would this be any different in practice from
| dynamic linking?
| wpollock wrote:
| > Steel-manning the idea, perhaps they would ship object
| files (.o/.a) and the apt-get equivalent would link the
| system? I believe this arrangement was common in the days
| before dynamic linking. You don't have to redownload
| everything, but you do have to relink everything.
|
| This was indeed comon for Unix. The only way to tune the
| systems (or even change the timezone) was to edit the
| very few source files and run make, which compiled those
| files then linked them into a new binary.
|
| Linking-only is (or was) much faster than recompiling.
| throwaway2046 wrote:
| Libraries already break their ABI so often that
| continuously rebuilding/relinking everything is inevitable.
| rlpb wrote:
| Debian manages perfectly well without.
| saidinesh5 wrote:
| Only because of the enormous efforts put in by debian
| package maintainers and it's infrastructure.
|
| If you're a an indie developer wanting your application
| to run on various debian based distros but the debian
| maintainers won't package your application, that's when
| you'd see why it's called DLL hell, how horribly
| fragmented the Linux packaging is and why even steam
| ships their whole run time.
| rlpb wrote:
| Everything _inside_ Debian is fine. That 's most of the
| ecosystem apart from the very new stuff that isn't mature
| enough yet. Usually the reason something notable stays
| out if Debian long term is when _that thing_ has such bad
| dependency hygiene that it cannot easily be brought up to
| standard.
| paddim8 wrote:
| Then you update those dependencies. Not very difficult with
| a package manager. And most dependencies aren't used by a
| ton of programs in a single system anyway. It is not a big
| deal in practice.
| rlpb wrote:
| This would only work if you use dynamic linking. Updating
| dependencies in a statically built distribution would
| have no effect.
| yxhuvud wrote:
| Honestly, that doesn't sound too bad if you have decent
| bandwidth.
| RicoElectrico wrote:
| That would be a good point if said shared libraries did not
| break binary backwards compatibility and behaved more like
| winapi.
| flohofwoe wrote:
| Dynamic libraries make a lot of sense as operating system
| interface when they guarantee a stable API and ABI (see Windows
| for how to do that) - the other scenarios where DLLs make sense
| is for plugin systems. But that's pretty much it, for anything
| else static linking is superior because it doesn't present an
| optimization barrier (especially for dead code elimination).
|
| No idea why the glibc can't provide API+ABI stability, but on
| Linux it always comes down to glibc related "DLL hell" problems
| (e.g. not being able to run an executable that was created on a
| more recent Linux system on an older Linux system even when the
| program doesn't access any new glibc entry points - the usually
| adviced solution is to link with an older glibc version, but
| that's also not trivial, unless you use the Zig toolchain).
|
| TL;DR: It's not static vs dynamic linking, just glibc being a
| an exceptionally shitty solution as operating system interface.
| uecker wrote:
| I do not think it is difficult compiling against versions by
| using a container.
| AshamedCaptain wrote:
| > (e.g. not being able to run an executable that was created
| on a more recent Linux system on an older Linux system even
| when the program doesn't access any new glibc entry points -
| the usually adviced solution is to link with an older glibc
| version, but that's also not trivial, unless you use the Zig
| toolchain).
|
| In the era of containers, I do not understand why this is
| "Not trivial". I could do it with even a chroot.
| mgaunard wrote:
| Static linking is also an optimization barrier.
|
| LTO is really a different thing, where you recompile when you
| link. You could technically do that as part of the dynamic
| linker too, but I don't think anyone is doing it.
|
| There is a surprisingly high number of software development
| houses that don't (or can't) use LTO, either because of
| secrecy, scalability issues or simply not having good enough
| build processes to ensure they don't breach the ODR.
| sebastos wrote:
| Genuine question - are there examples (research? old
| systems?) of the interface to the operating system being
| exposed differently than a library? How might that work
| exactly?
| abigail95 wrote:
| Why would I want to be constantly calling into code I have no
| control over, that may or may not exist, that may or may not be
| tampered with.
|
| I lose control of the execution state. I have to follow the
| calling conventions which let my flags get clobbered.
|
| To forego all of the above including link time optimization for
| the benefit of what exactly?
|
| Imagine developing a C program where every object file produced
| during compilation was dynamically linked. It's obvious why
| that is a stupid idea - why does it become less stupid when
| dealing with a separate library?
| uecker wrote:
| You call into dynamic libraries so that you do not need to
| recompile and distribute new binaries to all your users
| whenever there is a security issue or other critical fix in
| any of the dependencies.
| sebastos wrote:
| But if I get to Bring My Own Dependencies, then I know the
| exact versions of all my dependencies. That makes testing
| and development faster because I don't have to expend
| effort testing across many different possible platforms.
| And if development is just generally easier, then maybe
| it's easier to react expediently to security notices and
| release updates as necessary.. .
| gethly wrote:
| Isn't the sole reason why linux sucks(sucked?) for games and
| other software exactly that there is a gazillion of different
| libraries with different versions, so you have zero assumptions
| about the state of the OS, which makes making sw for it such a
| pain?
| paddim8 wrote:
| Yes. Premature optimisation when it comes to dynamic linking
| is the reason for why the year of the Linux desktop is far
| away in my opinion
| gethly wrote:
| I just remember Jonathan Blow mentioning this in one of his
| streams.
| Rochus wrote:
| So what we need is essentially a "libc virtualization".
|
| But Musl is only available on Linux, isn't it? Cosmopolitan
| (https://github.com/jart/cosmopolitan) goes further and is
| available also on Mac and Windows, and it uses e.g. SIMD and
| other performance related improvements. Unfortunately, one has to
| cut through the marketing "magic" to find the main engineering
| value; stripping away the "polyglot" shell-script hacks and the
| "Actually Portable Executable" container (which are undoubtedly
| innovative), the core benefit proposition of Cosmopolitan is
| indeed a platform-agnostic, statically-linked C standard (plus
| some Posix) library that performs runtime system call
| translation, so to say "the Musl we have been waiting for".
| sidewndr46 wrote:
| At the rate things are going we'll need a container
| virtualization layer as well, a docker for docker if you know
| what I mean
| miduil wrote:
| Do you mean something like gVisor?
| rafale wrote:
| "All problems in computer science can be solved by another
| level of indirection"
| Rochus wrote:
| ad infinitum ;-)
| johndough wrote:
| "... except for the problem of too many levels of
| indirection."
| dekhn wrote:
| that's solved with an off-by-one error
| binsquare wrote:
| I'm building in this space, I take a docker inside a microvm
| (vm-lite) approach.
|
| https://github.com/smol-machines/smolvm
| cwillu wrote:
| And the cycle continues
| binsquare wrote:
| It's just fun ;)
| sidewndr46 wrote:
| I wonder if inside the docker container we can run a
| sandboxed WASM runtime?
| VikingCoder wrote:
| I desperately want to write C/C++ code that has a web server
| and can talk websockets, and that I can compile with
| Cosmopolitan.
|
| I don't want Lua. Using Lua is crazy clever, but it's not what
| I want.
|
| I should just vibe code the dang thing.
| drowsspa wrote:
| I find it amazing how much the mess that building C/C++ code
| has been for so many decades seems to have influenced the
| direction technology, the economy and even politics has been
| going.
|
| Really, what would the world look like if this problem had been
| properly solved? Would the centralization and monetization of
| the Internet have followed the same path? Would Windows be so
| dominant? Would social media have evolved to the current
| status? Would we have had a chance to fight against the
| technofeudalism we're headed for?
| joshmarinacci wrote:
| How does this technical issue affect the economy and
| politics? In what way would the world be different just
| because we used a better linker?
| nacozarina wrote:
| existential crisis: so hot right now
| m463 wrote:
| Well, you could just look at things from an
| interoperability and standards viewpoint.
|
| Lots of tech companies and organizations have created
| artificial barriers to entry.
|
| For example, most people own a computer (their phone) that
| they cannot control. It will play media under the control
| of other organizations.
|
| The whole top-to-bottom infrastructure of DRM was put into
| place by hollywood, and then is used by every other program
| to control/restrict what people do.
| AshamedCaptain wrote:
| What I find amazing is why people continously claim glibc is
| the problem here. I have a commercial software binary from
| 1996 that _still works_ to this day. It even links with X11,
| and works under Xwayland.
|
| The trick? It's not statically linked, but dynamically
| linked. And it doesn't like with anything other than glibc,
| X11 ... and bdb.
|
| At this point I think people just do not know how binary
| compatibility works at all. Or they refer to a different
| problem that I am not familiar with.
| markus92 wrote:
| We (small HPC system) just upgraded our OS from RHEL 7 to
| RHEL 9. Most user apps are dynamically linked, too.
|
| You don't want to believe how many old binaries broke. Lot
| of ABI upgrades like libpng, ncurses, heck even stuff like
| readline and libtiff all changed just enough for linker
| errors to occur.
|
| Ironically all the statically compiled stuff was fine. Some
| small things like you mention only linking to glibc and X11
| was fine too. Funnily enough grabbing some old .so files
| from the RHEL 7 install and dumping them into
| LD_LIBRARY_PATH also worked better than expected.
|
| But yeah, now that I'm writing this out, glibc was never
| the problem in terms of forwards compatibility. Now running
| stuff compiled on modern Ubuntu or RHEL 10 on the older OS,
| now that's a whole different story...
| AshamedCaptain wrote:
| > Funnily enough grabbing some old .so files from the
| RHEL 7 install and dumping them into LD_LIBRARY_PATH also
| worked better than expected.
|
| Why "better than expected"? I can run the entire
| userspace from Debian Etch on a kernel built two days
| ago... some kernel settings need to be changed (because
| of the old glibc! but it's not glibc's fault: it's the
| kernel who broke things), but it works.
|
| > Now running stuff compiled on modern Ubuntu or RHEL 10
| on the older OS, now that's a whole different story...
|
| But this is a different problem, and no one makes
| promises here (not the kernel, not musl). So all the talk
| of statically linking with musl to get such type of
| compatibility is bullshit (at some point, you're going to
| hit a syscall/instruction/whatever that the newer musl
| does that the older kernel/hardware does not support).
| marcosdumay wrote:
| The problem of modern libc (newer than ~2004, I have no
| idea what that 1996 one is doing) isn't that old software
| stops working. It's that you can't compile software on your
| up to date desktop and have it run on your "security
| updates only" server. Or your clients "couple of years out
| of date" computers.
|
| And that doesn't require using newer functionality.
| AshamedCaptain wrote:
| But this is not "backwards compatibility". No one
| promises this type of "forward compatibility" that you
| are asking for . Even win32 only does it exceptionally...
| maybe today you can still build a win10 binary with a
| win11 toolchain, but you cannot build a win98 binary with
| it for sure.
|
| And this has nothing to do with 1996, or 2004 glibc at
| all. In fact, glibc makes this otherwise impossible task
| actually possible: you can force to link with older
| symbols, but that solves only a fraction of the problem
| of what you're trying to achieve. Statically linking /
| musl does not solve this either. At some point musl is
| going to use a newer syscall, or any other newer feature,
| and you're broke again.
|
| Also, what is so hard about building your software in
| your "security updates only" server? Or a chroot of it at
| least ? As I was saying below, I have a Debian 2006-ish
| chroot for this purpose....
| marcosdumay wrote:
| Windows dlls are forward compatible in that sense. If you
| use the Linux kernel directly, it is forward compatible
| in that sense. And, of course, there is no issue at all
| with statically linked code.
|
| The problem is with the Linux dynamic linking, and the
| idea that you must not statically link the glibc code.
| And you can circumvent it by freezing your glibc
| abstraction interface, so that if you need to add another
| function, you do so by making another library entirely.
| But I don't know if musl does that.
| AshamedCaptain wrote:
| > Windows dlls are forward compatible in that sense.
|
| If you want to go to such level, ELF is also forward
| compatible in that sense.
|
| This is completely irrelevant, because what the developer
| is going to see is the binaries he builts in XP SP3 no
| longer work in XP SP2 because of a link error: the
| _statically linked_ runtime is going to call symbols that
| are not in XP SP2 DLLs (e.g. the DecodePointer debacle).
|
| > If you use the Linux kernel directly, it is forward
| compatible in that sense.
|
| Or not, because there will be a note in the ELF headers
| with the minimum kernel version required, which is going
| to be set to a recent version even if you do not use any
| newer feature. (unless you play with the toolchain) (PE
| has similar field too, leading to the "not a valid win32
| executable" messages).
|
| > And, of course, there is no issue at all with
| statically linked code.
|
| I would say statically linked code is precisely the root
| of all these problems.
|
| In addition to bring more problems of its own. E.g. games
| that dynamically link with SDL can be patched to have any
| other SDL version, including one with bugfixes for X
| support, audio, etc. Games that statically link with SDL?
| Sorry..
|
| > And you can circumvent it by freezing your glibc
| abstraction interface, so that if you need to add another
| function, you do so by making another library entirely.
| But I don't know if musl does that.
|
| Funnily, I think that is exactly the same as the solution
| I'm proposing for this conundrum: just (dynamically) link
| with the older glibc ! Voila: your binary now works with
| glibc from 1996 and glibc from 2026.
|
| Frankly, glibc is already the project with the best
| binary compatibility of the entire Linux desktop , if not
| the only one with a binary compatibility story at all .
| The kernel is _not_ better in this regard (e.g.
| /dev/dsp).
| marcosdumay wrote:
| If you use only features available on the older version,
| for sure, you can compile your software in Win-7 and have
| it run in Win-2000. Without following any special
| procedure.
|
| I know, I've done that.
|
| > just (dynamically) link with the older glibc!
|
| Except that the older glibc is unmaintained and very hard
| to get a hold of and use. If you solve that, yeah, it's
| the same.
| Conscat wrote:
| If the APE concept isn't appealing to you, you may be
| interested in the work on LLVM libC. My friend recently
| delivered an under-appreciated lecture on the vision:
|
| https://youtu.be/HtCMCL13Grg
|
| tl;dw Google recognizes the need for a statically-linked
| _modular_ latency sensitive portable POSIX runtime, and they
| are building it.
| weebull wrote:
| If you're using dlopen(), you're just reimplementing the dynamic
| linker.
| 112233 wrote:
| that's cute, but dismissive, sort of like "if you use popen(),
| you are reimplementing bash". There is so much hair in ld
| nobody wants to know about -- parsing elf, ctors/dtors, ...
| pilif wrote:
| Isn't this asking for the exact trouble musl wanted so spare you
| from by disabling dlopen()?
| netbioserror wrote:
| I've been statically linking Nim binaries with musl. It's
| fantastic. Relatively easy to set up (just a few compiler flags
| and the musl toolchain), and I get an optimized binary that is
| indistinguishable from any other static C Linux binary. It runs
| on any machine we throw it at. For a newer-generation systems
| language, that is a massive selling point.
| zoobab wrote:
| I have an idea for a static linux distribution based on musl,
| with either an Alpine rebuild or Gentoo-musl:
|
| http://stalinux.wikidot.com
|
| The documentation to make static binary with GLibc is sparce
| for a reason, they don't like static binaries.
| cb321 wrote:
| Yeah. I've been doing this for almost 10 years now. It's not
| APE/cosmopolitan (which also "kinda works" with Nim but has
| many lowest common denominator platform support issues, e.g.
| posix_fallocate). However, it does let you have very cross-
| Linux portable binaries. Maybe beyond Linux.
|
| Some might appreciate a concrete instance of this advice inline
| here. For `foo.nim`, you can just add a `foo.nim.cfg`:
| @if gcc: gcc.exe = "musl-gcc"
| gcc.linkerexe = "musl-gcc" passL = "-static
| -s" @end
|
| There is also a "NimScript" syntax you could use a `foo.nims`:
| if defined gcc: # nim.cfg runs faster than NimScript
| switch "gcc.exe" , "musl-gcc" switch
| "gcc.linkerexe", "musl-gcc" switch "passL" ,
| "-static -s"
| ValdikSS wrote:
| `dlopen`'ing system libraries is an "easy" hack to try to
| maintain compatibility with wide variety of libraries/ABIs. It's
| barely used (I know only of SDL, Small HTTP Server, and now
| Godot).
|
| Without dlopen (with regular dynamic linking), it's much harder
| to compile for older distros, and I doubt you can easily
| implement glibc/musl cross-compatibility at all in general.
|
| Take a look what Valve does in a Steam Runtime:
| - https://gitlab.steamos.cloud/steamrt/steam-runtime-
| tools/-/blob/main/docs/pressure-vessel.md -
| https://gitlab.steamos.cloud/steamrt/steam-runtime-
| tools/-/blob/main/subprojects/libcapsule/doc/Capsules.txt
| surajrmal wrote:
| Binary comparability extends beyond the vide that runs in your
| process. These days a lot of functionality occurs by way of IPC
| which has a variety of wire protocols depending on the interface.
| For instance there is dbus, Wayland protocols, varlink, etc. Both
| the wire protocol, and the APIs built on top need to retain
| backwards comparability to ensure Binary compatibility. Otherwise
| you're not going to be able to run on various different Linux
| based platforms arbitrarily. And unlike the kernel, these
| userspace surfaces do not take backwards compatibility nearly as
| important. It's also much more difficult to target a subset of
| these APIs that are available on systems that are only 5 years
| old. I would argue API endpoints on the web have less risk here
| (although those break all the time as well)
| leni536 wrote:
| Do I get this right that this effectively dlopens glibc
| (indirectly) into an executable that is statically linked to
| musl? How can the two runtimes coexist? What about malloc/free?
| AFAIK both libc's allocators take ownership of brk, that can't be
| good. What about malloc/free across the dynamic library
| interface? There are certainly libraries that hand out allocated
| objects and expect the user to free them, but that's probably
| uncommon in graphics.
| Splizard wrote:
| You have to tell musl to use mmap instead of brk. You're right
| that it doesn't work in all cases but as long as you switch TLS
| on calls (and callbacks), at least with a project the size of
| Godot, you can approach a workable solution.
| leni536 wrote:
| > You have to tell musl to use mmap instead of brk.
|
| How do I do that? Is there a documented configuration of
| musl's allocator?
| dunder_cat wrote:
| Related discussion (the actual project is mentioned in the
| issue): "Detour: Dynamic linking on Linux without Libc"
| https://news.ycombinator.com/item?id=45740241
| aspbee555 wrote:
| I managed to get this combo going not too long ago with my musl
| rust app but I found that even after it all was compiled and
| loading the lib it did not function properly because the library
| I loaded still depended on libc functions. even with everything
| compiled into a huge monolithic musl binary it couldn't find
| something graphics related
|
| I eventually decided to keep the tiny musl app and make a
| companion app in a secondary process as needed (since the entire
| point of me compiling musl was cross platform linux
| compatibility/stability)
| tuhgdetzhh wrote:
| The best binary compatibily you can get on Linux is via Wine.
|
| Source: https://blog.hiler.eu/win32-the-only-stable-abi/
___________________________________________________________________
(page generated 2026-01-26 23:01 UTC)