大多数在线资源都表明您可以静态链接glibc,但不建议这样做。例如,CentOS软件包仓库:
glibc-static软件包包含用于静态链接的C库静态库。除非您静态链接,否则您不需要它们,这是极其不建议的。
这些来源很少(或从不)说明为什么这是一个坏主意。
大多数在线资源都表明您可以静态链接glibc,但不建议这样做。例如,CentOS软件包仓库:
glibc-static软件包包含用于静态链接的C库静态库。除非您静态链接,否则您不需要它们,这是极其不建议的。
这些来源很少(或从不)说明为什么这是一个坏主意。
其他回答提供的原因是正确的,但并不是最重要的原因。
glibc不应该被静态链接的最重要原因是它在内部广泛使用dlopen
来加载NSS(Name Service Switch)模块和iconv
转换。这些模块本身是对C库函数的引用。如果主程序与C库动态链接,那么没有问题。但是如果主程序与C库静态链接,dlopen
就必须加载一个第二份C库以满足模块的加载需求。
这意味着你的“静态链接”程序仍然需要一个libc.so.6
的副本存在于文件系统中,还需要NSS或iconv
或任何其他模块本身,以及模块可能需要的其他动态库,如ld-linux.so.2
、libresolv.so.2
等。这不是人们通常希望在静态链接程序时出现的情况。
stdout
缓冲区,谁可以使用非零参数来调用sbrk
等。 glibc内部有一堆防御性逻辑来尝试使其工作,但从未被保证过。getaddrinfo
或iconv
,但是语言环境支持在内部使用iconv
,这意味着任何stdio.h
函数都可能触发对dlopen
的调用,而您无法控制此操作,用户的环境变量设置会影响到它。iconv
,那么事情会变得更糟,特别是当一个“静态链接”可执行文件在一个发行版上构建,然后复制到另一个发行版时。在不同的发行版上,iconv
模块有时位于不同的位置,因此在Red Hat发行版上构建的可执行文件可能无法在Debian上正确运行,这与静态链接可执行文件的初衷完全相反。nscd
)。 - zwolstdio.h
的 C 程序可以在 /lib 中没有任何库的情况下工作。我需要用这种方法运行 lilo 程序。 - Joshuaglibc
接口已经被POSIX、C和C++标准等规范化并记录。例如,fopen()
函数遵循C标准,pthread_mutex_lock()
遵循POSIX标准。
glibc
/内核接口并未被规范化。 fopen()
在底层使用open()
还是openat()
?或者其他的什么?明年会使用什么?你不知道。glibc
/内核接口发生更改,使用静态链接glibc
的程序将无法再正常工作。libc
。
静态链接——它去哪里了?
使用Solaris 10,您无法再构建静态可执行文件。这并不是因为ld(1)不允许静态链接或使用存档文件,而是因为不再提供libc.a,即libc.so.1的存档版本。该库提供了用户空间与内核之间的接口,没有此库,创建任何形式的应用程序都相当困难。似乎对Linux内核接口的稳定性进行了严重高估。请参见Linux内核API更改/添加以获取详细信息。总结如下: