This is a good write up from the point of view of a C/C++ programmer, since it gives a fair breakdown of where that extra space is going and rightly points out that statically linked C/C++ executables are going to be large as well. It's also a fun tour of how to access the syscall interface directly from Rust and to perform optimizations that most C and C++ programmers wouldn't ever perform perhaps outside of the most space constrained embedded projects.
I take a minor issue with the handwaving away (not just in this article but with others as well) of glibc and the suggestion that it can just be replaced with musl or another libc. There's a reason that glibc doesn't officially support static linking, and that is NSS, and PAM.
If all you need is a static executable for your Docker container or whatever that reads user/group information and authenticates out of flat files in /etc, then go for it. But in the "enterprise" space things like LDAP, Active Directory, 2FA etc. are real, and if your application needs to support those, then you're going to need glibc and its dependency on dlopen() and friends.
And this goes for every language which has a dependency on your chosen libc as well (which let's face it, is a large majority at least in the Linux world), if you want to use NSS and PAM modules.
OK fist I'm not defending c or c++ but trying to fix incorrect information:
> ...rightly points out that statically linked C/C++ executables are going to be large as well.
This is false, and both how a library is structured how linkers work, if you statically link parts of musl expect a somewhat tiny size increase.
> There's a reason that glibc doesn't officially support static linking, and that is NSS, and PAM.
That and the code isn't structured for static linking as there are dependency chains pulling in many symbols.
> ...most C and C++ programmers wouldn't ever perform perhaps outside of the most space constrained embedded projects.
This is because syscalls are os specific and depending on the os unstable. Also Linux has an interesting way of encoding errno into the ret val (maybe others too?) not to mention vdso 'syscalls'.
> ...glibc and its dependency on dlopen() and friends.
If $code doesn't work on musl 99.9% of the time its due to $code, also musl has dlopen and a dyn linker otherwise alpine wouldn't work.
Thank you for the technical clarifications. In the boring, corporate, enterprise software bubble in which I have mostly worked for 25 years, musl/busybox/Alpine are barely a blip on the radar. I have not ever seen an Alpine Linux install in 25 years, unless it is the basis of various busybox based appliances and I've not noticed. Certainly never seen it used for running "mission critical" bloated Java enterprise apps etc.
So within my comment I thought it was implicitly clear I was referring to glibc based distributions, for example Redh^H^H IBM.
You CAN statically link binaries against glibc on these distributions, and in many cases it will work. However NSS and PAM will not work in my experience. Is it a generally a good idea to static link against glibc? No.
> If $code doesn't work on musl 99.9% of the time its due to $code, also musl has dlopen and a dyn linker otherwise alpine wouldn't work.
Is sssd officially supported on Alpine Linux? Does it just work out of the box? It seems to be in "testing" branch from what I can see with over 600 open bugs.
There is a reason that shareholders of large organizations want to pay a large, established Linux vendor for support, regardless of whether or not their engineers will ever use the support or not. They want to pay for stability/security updates. They are paying for a Linux distribution that 3rd party application providers have certified their application for.
They want LDAP/AD and other pluggable PAM modules to work out of the box without too much tinkering. Alpine Linux may fit that criteria for all I know. Doesn't matter. My employers wouldn't use it whether I wanted to or not.
Not saying that I like how things have turned out for Enterprise Linux necessarily, but it is what it is. Redhat and clones absolutely DOMINATE this particular space, at least in the USA, UK and Australia.
> They want LDAP/AD and other pluggable PAM modules to work out of the box without too much tinkering.
PAM works fine with musl even though the main implementation of PAM is horrible for security. Also PAM isn't tied to a libc so I don't understand why its mentioned, the glibc implementation of NSS tied to libc but there are other implementations of NSS.
> If all you need is a static executable for your Docker container or whatever that reads user/group information and authenticates out of flat files in /etc, then go for it.
If you're using a Docker image, then that's your statically-linked binary, for all intents and purposes. It won't change sizes much if you link libc statically or dynamically (esp. if you're running in an Alpine container with musl).
Substitute Docker for another container technology, or even "IOT device" in my comment if that helps. The point i'm making is not about the size of the binary, size or type of container that it runs in (if at all), but about the features it can/will support if you rip out glibc and replace it in a fit of rage with musl or similar which seems to be somewhat of a fashion at the moment.
> There's a reason that glibc doesn't officially support static linking, and that is NSS, and PAM.
Thanks for pointing this out; I'd hit this problem in the past and it's annoying to see people keep promoting static linking as a silver bullet when there is a genuine purpose to dynamically linking the name services.
I take a minor issue with the handwaving away (not just in this article but with others as well) of glibc and the suggestion that it can just be replaced with musl or another libc. There's a reason that glibc doesn't officially support static linking, and that is NSS, and PAM.
If all you need is a static executable for your Docker container or whatever that reads user/group information and authenticates out of flat files in /etc, then go for it. But in the "enterprise" space things like LDAP, Active Directory, 2FA etc. are real, and if your application needs to support those, then you're going to need glibc and its dependency on dlopen() and friends.
And this goes for every language which has a dependency on your chosen libc as well (which let's face it, is a large majority at least in the Linux world), if you want to use NSS and PAM modules.