Linux静态链接已经死了? [英] Linux static linking is dead?
问题描述
2.22。即使静态链接的程序也需要一些共享库
,这对我来说是不可接受的。
我可以做什么?
{AJ} NSS(详情请输入'info
libc'Name Service Switch'' )如果没有共享的
库,
不会正常工作。 NSS允许通过只更改一个配置
文件(/etc/nsswitch.conf)而不用
重新链接任何程序来使用不同的
服务(例如NIS,文件,db,hesiod)
。唯一的
缺点是现在静态的
库需要访问共享的
库。这是由GNU C库透明地处理
。
解决方案是使用
--enable-static-nss配置glibc。在这种情况下,您可以创建一个静态二进制文件,
只使用服务dns和文件
(为此更改/etc/nsswitch.conf)。
您需要明确链接
所有这些服务。例如:
gcc -static test-netdb.c -o test-netdb \
-Wl, - -start-group -lc -lnss_files -lnss_dns -lresolv -Wl, - end-group
这种方法的问题是
,您必须将使用NSS例程的每个静态
程序与
所有这些库链接在一起。
{UD} In事实上,人们不能再说,用这个选项
编译的libc正在使用NSS。没有开关
了。因此,使用
--enable-static-nss会高度
不是 ,因为这会导致$ b $上的程序行为b系统不一致。
关于这个事实,现在有什么合理的方法来在Linux上创建一个全功能的静态构建或者静态链接在Linux上完全死掉了?我的意思是静态构建其中:
- 的行为与
动态构建完全相同(static-nss with
);
- 适用于glibc环境和Linux版本的合理变体;
我不知道在哪里可以找到历史参考,但是,静态链接在GNU系统上死掉了。 (我相信它在从libc4 / libc5过渡到libc6 / glibc 2.x的过程中死掉了。)
该功能根据以下原因被视为无用:
-
安全漏洞。静态链接的应用程序甚至不支持libc的升级。如果应用程序在包含lib漏洞的系统上链接,那么它将在静态链接的可执行文件中永久存在。
代码膨胀。如果许多静态链接的应用程序在同一个系统上运行,那么标准库不会被重用,因为每个应用程序都包含它自己的所有内容。 (尝试
du -sh / usr / lib
以了解问题的严重程度。) 尝试从10至15年前开始挖掘LKML和glibc邮件列表档案。我很确定很久以前,我看到过有关LKML的一些事情。
In fact, -static gcc flag on Linux doesn't work now. Let me cite from the GNU libc FAQ:
2.22. Even statically linked programs need some shared libraries which is not acceptable for me. What can I do?
{AJ} NSS (for details just type `info libc "Name Service Switch"') won't work properly without shared libraries. NSS allows using different services (e.g. NIS, files, db, hesiod) by just changing one configuration file (/etc/nsswitch.conf) without relinking any programs. The only disadvantage is that now static libraries need to access shared libraries. This is handled transparently by the GNU C library.
A solution is to configure glibc with --enable-static-nss. In this case you can create a static binary that will use only the services dns and files (change /etc/nsswitch.conf for this). You need to link explicitly against all these services. For example:
gcc -static test-netdb.c -o test-netdb \ -Wl,--start-group -lc -lnss_files -lnss_dns -lresolv -Wl,--end-group
The problem with this approach is that you've got to link every static program that uses NSS routines with all those libraries.
{UD} In fact, one cannot say anymore that a libc compiled with this option is using NSS. There is no switch anymore. Therefore it is highly recommended not to use --enable-static-nss since this makes the behaviour of the programs on the system inconsistent.
Concerning that fact is there any reasonable way now to create a full-functioning static build on Linux or static linking is completely dead on Linux? I mean static build which:
- Behaves exactly the same way as dynamic build do (static-nss with inconsistent behaviour is evil!);
- Works on reasonable variations of glibc environment and Linux versions;
Concerning that fact is there any reasonable way now to create a full-functioning static build on Linux or static linking is completely dead on Linux?
I do not know where to find the historic references, but yes, static linking is dead on GNU systems. (I believe it died during the transition from libc4/libc5 to libc6/glibc 2.x.)
The feature was deemed useless in light of:
Security vulnerabilities. Application which was statically linked doesn't even support upgrade of libc. If app was linked on system containing a lib vulnerability then it is going to be perpetuated within the statically linked executable.
Code bloat. If many statically linked applications are ran on the same system, standard libraries wouldn't be reused, since every application contains inside its own copy of everything. (Try
du -sh /usr/lib
to understand the extent of the problem.)
Try digging LKML and glibc mail list archives from 10-15 years ago. I'm pretty sure long ago I have seen something related on LKML.
这篇关于Linux静态链接已经死了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!