Comment by Spivak
3 years ago
Glibc is GNU/Linux though and cannot be avoided when distributing packages to end users. If you want to interact with the userspace to do things get users, groups, netgroups, or DNS queries you have to use glibc functions or your users will hit weird edge cases like being able to resolve hosts in cURL but not your app.
Now, do I think it would make total sense for syscall wrappers and NSS to be split into their own libs (or dbus interfaces maybe) with stable ABIs to enable other libc's, absolutely! But we're not really there. This is something the BSD's got absolutely right.
There are other libc implementations that work on Linux with various tradeoffs. Alpine famously uses musl libc for a lightweight libc for containers. These alternate libc implementations implement users/groups/network manipulation via well-known files like /etc/shadow, /etc/passwd, etc. You could fully statically link one of these into your app and just rely on the extremely stable kernel ABI if you're so interested.
We're not disagreeing. You can, of course, use other libc's on Linux the kernel, but you cannot use other libc's on GNU/Linux the distro that uses glibc without some things not working. This can be fine on your own systems so long as you're aware of the tradeoffs but if you're distributing your software for use on other people's systems your users will be annoyed with you.
Even Go parses /etc/nsswitch.conf and farms out to cgo when it finds a module it can't handle. This technically doesn't work because there's no guarantee that the hosts or dns entries in nsswitch have consistent behavior, it's just the name of a library you're supposed to dlopen. On evil, but valid, distro resolv.conf points to 0.0.0.0 and hosts module reads an sqlite file.
> you cannot use other libc's on GNU/Linux the distro that uses glibc without some things not working
As the comment your replying to points out, you can statically link your libc requirements and work on any Linux distro under the sun.
You can also LD_PRELOAD any library you need, and also work on any Linux distro under the sun. This is effectively how games work on Windows too, they ship all their own libraries. Steam installs a specific copy of the VCREDIST any given game needs when you install the game.
If you are not releasing source code, it's unreasonable to think the ABIs you require will just be present on any random computer. Ship the code you need, it's not hard.
> Now, do I think it would make total sense for syscall wrappers and NSS to be split into their own libs (or dbus interfaces maybe) with stable ABIs to enable other libc's, absolutely!
I worked on this a few years ago: liblinux.
https://news.ycombinator.com/item?id=28283632
But there are other "Linux"'s that are not GNU/Linux which was I think the point. Like Android, which doesn't use glibc, and doesn't have this mess. I think that was one of the things people used to complain about, that Android didn't use glibc, but since glibc seems to break ABI compatibility kinda on the regular that was probably the right call.
Solaris had separate libc, libnss, libsocket, and libpthread, I think?
Unlike many languages, Go doesn't use any libc on Linux. It uses the raw kernel API/ABI: system calls. Which is why a Go 1.18 binary is specified to be compatible with kernel version 2.6.32 (from December 2009) or later.
There are trade-offs here. But the application developer does have choices, they're just not no-cost.