2023-04-09
On Linux, you can't usefully statically link programs using NSS
In Linux (and other operating systems), NSS (Name Service Switch) is a mechanism that lets the system implement name resolution for various sorts of name lookups through a system of dynamically loaded shared objects, configured through /etc/nsswitch.conf. Also in Linux, in theory, you can statically link programs through the '-static' argument to various programs like GCC and the Go toolchain. Statically linking program executables because this can avoid situations where you can't run an executable on an older Linux version than it was built one.
You might wonder how NSS plays together with statically linking your executables. The answer is that it doesn't:
warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
What you get is a statically linked executable that still requires the glibc version you linked with.
On the one hand, this is unappealing. On the other hand, there is basically no way out. NSS modules are shared objects, and they may use more or less arbitrary bits of the C library. Since they may well have been compiled against the current version of glibc, these bits may require that glibc version in order to work right, through symbol versioning or otherwise. They also have to be able to resolve random symbols in the C library, symbols that may not have been used in your program and so were omitted from your static executable.
(There are also more direct issues of how dynamic lookup and indirect calls are implemented in shared objects, but let's handwave those and assume that you could in theory build versions of those out of your static program at run time.)
Pretty much the only good answer is that basically you may need the entire shared glibc in order to make a NSS shared object happy. So you'd better have that glibc available.
Since I mostly haven't been trying to statically link my (C) executables for some time for various reasons, this probably won't make much of a difference to me. Linux distributions have been making static linking more and more of a hassle in general, with things like missing static versions of dynamic libraries, or at least hidden ones that live in obscure packages. Although I see that there is a readily available libreadline.a in Ubuntu; libreadline has been one of my pain points over the years.
(This is something I could have known long ago if I really paid attention, but I only had my nose rubbed into it today for reasons beyond the scope of this entry.)