One of the reasons I've switched some builds over to musl over glibc, is that I found that glibc linking is brittle if you're going to run a binary over multiple distros in various container environments. Particularly if you want one binary to work on linux across RH and Debian/Ubuntu derived distros or even different ages of distro.
As much as I think about Linux compared to the competition in desktop the more I realize this is right
"If it's a bug people rely on it's not a bug, it's a feature" Let me guess, he was thinking of the memcpy issue that broke flash. Or maybe something else. And I agree, nobody cares
The spec says that because it was the 70s and nobody had thought better of that or how things would work 30 yrs on, and going with it does not make sense.
And I feel the pain of this hardheadedness when any library deprecates an API when they didn't need. "Oh but it's cleaner now" Again, nobody cares
The real comparison is: musl does not provide any preprocessor macro to tell you what libc you're using.
And it has so many weird quirks that you need to work around.
***
Static linking makes linking more painful, especially regarding global constructors (which are often needed for correctness or performance). This is not a musl-specific issue, but a lot of people are interested in both.
Just do your builds on the oldest supported system, and dynamic linking works just fine. You can relative-rpath your non-libc dependencies if they would be a pain to install, though think twice about libstdc++.
***
The major advantage of MUSL is that if you're writing a new OS, it's much easier to port.
> musl does not provide any preprocessor macro to tell you what libc you're using.
> And it has so many weird quirks that you need to work around.
I was under the impression that musl stuck closely to the standard, and glibc frequently did its own thing, so 1. it's not musl that's quirky, 2. if you need to detect something, just detect glibc.
There are places where MUSL implements a broad set of GLIBC extensions in order to actually be useful. However, it does not indicate that in any way, and sometimes violates the conditions that GLIBC documents. This requires workarounds.
There are places where MUSL implements a standard interface in a particular way. If you're lucky, this "just" means giving up on performance if you don't know you're using MUSL.
Sometimes MUSL implements its own ABI-incompatible extensions. The time64 transition, for example, is a huge mess regardless, but musl provides no blessed way to figure out what's going on. The only reason it's not an even bigger disaster is that almost nobody uses musl.
> What is the comparison between using musl and traditional glibc?
you get weird bugs and failures that don't happen with glibc (like the incomplete dns resolving routines that would fail under some conditions) but you can brag about saving 30-40 mb of disk space.
this project seems to be compromising on quality overall, in the name of having smaller size.
Even BearSSL, by their own website is beta-quality: "Current version is 0.6. It is now considered beta-quality software" (from https://bearssl.org/).
I maintain a large codebase, widely deployed, cross compiled to many cpu architecures that's built atop musl. You're right that historically in the context of people blindly using alpine for their container base that sort of thing might be the case. The newest version of musl solves the thing you're describing and in general most of the complaints about malloc perf or otherwise have been addressed. Avoiding musl to me seems like an outdated trope, but there was a time wherein that take was valid indeed.
At least we have light at the end of the tunnel now. This is a tremendous improvement from the previous status quo of the musl maintainers not even agreeing that it's a problem.
What's a better option for static linking? glibc is religiously against it; they have far worse dogmatic beliefs than this musl DNS thing. I'd be happy to choose a better alternative if one exists, but if one does not, I have to live with the options at hand. From where I'm standing, musl seems like the only game in town. uClibc doesn't seem like it's appropriate for general purpose Linux applications on desktop computers (maybe I'm wrong?).
from my understanding glibc is not "religiously" against it, they're against it for technical reasons. In the sense, this is not a dogma. It's about internal details of their implementations.
Static linking doesn't actually solve any problem. Just use dynamic linking with (probably relative) rpath, and compile against a sufficiently old libc.
There's some common FUD about rpath being insecure, but that only applies if the binary is setuid (or otherwise privileged) and the rpath is writable by someone other than the binary's owner (all relative rpaths are writable since you can use symlinks; absolute rpaths are writable if they point to /tmp/ or a similar directory, which used to be common on buildbots).
This is really not hard; working around all static linking's quirks is harder.
You have to know the internals of your dependencies so you can link them explicitly, recursively. (admittedly, pkg-config helps a ton, but not all libraries ship (good) .pc files)
Global constructors no longer reliably fire unless you are extremely careful with your build system, nor do they run in a predictable order (e.g. you can call a library before it is actually initialized, unlike dynamic linking where only preinit - which nobody uses - is weird), nor can you defer them until dlopen time if you want (which is, admittedly, overdone).
It's possible to link to parts of multiple versions of a library (remember, you have to recurse into your dependencies), as opposed to dynamic libraries where at least you're guaranteed all-or-nothing (which is much easier to detect).
Linking is slower since it always has to be redone from scratch.
Not resilent against system changes. For example, old versions of `bash-static` (grab them from e.g. Debian snapshot and extract them manually; don't install them) are no longer runnable on modern systems since certain system files have changed formats, whereas the dynamically-linked `bash` packages still run just fine.
It also encourages bad stability habits, leading to the equivalent of NPM hell, which is far worse than DLL hell ever was.
You can't use LD_PRELOAD or other dynamic interception tools.
There are probably more reasons to avoid static linking, but I'm trying to ignore the handful from the popular lists.
Thanks! Most of those seem like a fair trade-off for portability… for an app.
I’m not sure it’s a great idea for an OS as in the OP, but I do like that they claim accurate incremental rebuilds, to ensure everything get updated. Certainly an interesting experiment!
Edit: just to clarify, I meant "app" as in "something that isn't part of the OS/distribution".
A small point on that last bit. The bearssl authors are pretty conservative when it comes to development milestones, I'd guess that their 0.6 would be pretty solid :)
> I'd guess that their 0.6 would be pretty solid :)
Would you accept that kind of reasoning for software running on your pacemaker, or on your insuline pump?
I think we should respect the developers here: they're not claiming production quality level (they're claiming beta-quality level) so it's not correct to use that library in any kind of product and claim any kind of production-level quality.
> Would you accept that kind of reasoning for software running on your pacemaker, or on your insuline pump?
God helps me I wouldn't implant anything so fundamental in my body with hard dependencies on encrypted communication to a remote agent elsewhere, no matter the advantage.
If you go by version number and anything < 1.0 being not production ready, I recommend avoiding reading any of the dependency files for large software products which are often used in produciton, they might cause you some concern...
Speaking from heavy experimentation and experience, [0] glibc has some more optimized routines but musl has significantly less bloat. If you are haphazardly calling libc functions left and right for everything and have a generally unoptimized code base, your code may fare better better with glibc. But musl’s smaller codebase is a win for faster startup and micro optimizations otherwise - and that’s without lto where it stands to gain more.
I don’t think that was around back then but I can add it to the backlog of things to try for next round. Does that play nice with rust? Presumably I’d have to at least build the standard library from scratch (which I’d want to do against musl as a separate benchmark anyway since it’s now a single environment variable away).
(Not that the codebase makes much string function usage.)
> in addition to its direct usage of AVX2 functions and types, it also made a call to the BZHI and LZCNT intrinsics/asm instructions – which rustc/llvm do not recognize as being supported via the avx2 feature! So although (to the best of this developer’s knowledge) there does not exist a processor on the face of this planet that supports AVX2 but doesn’t support BZHI and LZCNT
Looks like a "bug" or better put needed enhancement to LLVM.
No it doesn't. The MIT license is objectively less restrictive than the LGPL. Whether it's a good or bad thing to be less restrictive is a matter of opinion, but whether or not it is less restrictive is a matter of fact.
Lots of software licensed as MIT is distributed under a proprietary sublicense, which is as restrictive as it gets. That isn't the case with GPL licenses.
It is a matter of fact that it's a matter of perspective.
Is there performance differences between the two?
I have been seeing musl used more and more in both Rust and Zig ecosystems lately.