16

I'm trying to compile a statically linked binary with GCC and I'm getting warning messages like:

warning: Using 'getpwnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

I don't even know what getwnam_r does, but I assume it's getting called from inside some higher level API. I receive a similar message for gethostbyname.

Why would it not be possible to just statically link these functions in like every other function?

dsimcha
  • 67,514
  • 53
  • 213
  • 334
  • 1
    I believe it's because some of these functions are provided by the operating system kernel itself, or are specific to different versions of the kernel, but I'm not certain enough that I'm willing to put it as an answer. – Max E. Nov 15 '11 at 17:31

2 Answers2

30

Function calls that need access to NSS or iconv need access will open other libs dynamically, since NSS needs plugins to work (the helper modules like pam_unix.so). When the NSS system dlopens these modules, there will be two conflicting versions of glibc - the one your program brought with it (statically compiled in), and the one dlopen()ed by NSS dependencies. Shit will happen.

This is why you can't build static programs using getpwnam_r and a few other functions.

thiton
  • 35,651
  • 4
  • 70
  • 100
  • Great answer. So the issue isn't static vs. dynamic it is just that there's a set of known functions that use dlopen? It's nice of the compiler to warn you, it's got to be a hard-coded list right, there's no automatic way to warn against libs that call dlopen. – kbyrd Nov 15 '11 at 17:37
  • 1
    @kbyrd: well, it's the linker, and it already had a list for complaining loudly about various things (e.g: use of `gets`) – ninjalj Nov 15 '11 at 19:24
  • 7
    The linker doesn't have a hard-coded list either. The warnings actually come from libc.a itself. Here is how it is done: http://repo.or.cz/w/glibc.git/blob/HEAD:/nss/getXXbyYY.c#l155 Also, it *is* quite possible to link the application statically (it's just a warning). But if you don't heed the warning and run the app on a system with different glibc, things will end up badly. – Employed Russian Nov 16 '11 at 03:19
  • 1
    @EmployedRussian: so each warning is in a `.gnu.warning.` section that the linker reads. Nice to know. – ninjalj Nov 16 '11 at 21:45
  • @kbyrd: after Emploted Russian wonderful comment, I have looked at how the linker warnings are done, my findings are at http://ninjalj.blogspot.com/2011/11/your-own-linker-warnings-using-gnu.html – ninjalj Nov 17 '11 at 00:29
-2

AFAIK, it's not impossible to fully statically link an application.

The problem would be incompatibility with newer library versions which might be completely different. Say for example printf(). You can statically link it, but what if in a future that printf() implementation changes radically and this new implementation is not backward-compatible? Your appliction would be broken.

Please someone correct me if I'm wrong here.

m0skit0
  • 25,268
  • 11
  • 79
  • 127
  • that doesn't even make sense, of course you can, you aren't typically going to want to in a modern environment, because of the standardization of modern libraries, you wouldn't want to statically link `stdlib` or `stdio` for instance. But if you were to require something like openssl of a specific version you certainly could. – Grady Player Nov 15 '11 at 17:30
  • I don't understand what you mean. Maybe you didn't understand what I meant. I meant you CAN statically link the functions. The problem would be if those libraries are architecture or design dependant. For example, if OS system calls change and you have statically linked against old OS libraries, those will not work. I hope I made my point clear. – m0skit0 Nov 15 '11 at 17:35
  • Your idea as expressed in the comment is valid, but the line "incompatibility with newer library versions" in the answer needs to go - you are talking about incompatibility with the kernel interface, not the libraries, since in a fully statically linked executable compatible versions of all required library functions are already bundled. – Chris Stratton May 14 '12 at 16:13
  • Yes, I was talking about the kernel interface, which might change and thus newer libraries would change as well. The answer is still valid. Probably not expressed at its best, but it's valid. Also my comment above clarifies this I think. – m0skit0 May 14 '12 at 21:00