一尘不染

Linux静态链接已死?

linux

实际上,Linux上的 -static gcc标志现在不起作用。让我从GNU libc常见问题中引用:

2.22。 即使是静态链接程序也需要一些共享库,这对我来说是不可接受的。我能做什么?

{AJ} NSS(有关详细信息,请键入“ info
libc“名称服务开关”“)在没有共享库的情况下无法正常工作。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}实际上,不能再说使用此选项编译的libc正在使用NSS。 不再有开关。因此, 强烈 建议 不要 使用–enable-
static-nss,因为这会使系统上程序的行为不一致。

关于这一事实,现在是否有任何合理的方法可以在Linux上创建功能齐全的静态构建,或者静态链接在Linux上完全无效?我的意思是静态版本:

  • 行为与动态构建完全相同(行为不一致的static-nss是邪恶的!);
  • 适用于合理的glibc环境和Linux版本;

阅读 294

收藏
2020-06-02

共1个答案

一尘不染

关于这一事实,现在是否有任何合理的方法可以在Linux上创建功能齐全的静态构建,或者静态链接在Linux上完全无效?

我不知道在哪里可以找到历史参考,但是是的,静态链接在GNU系统上已失效。(我相信它在从libc4
/ libc5过渡到libc6 / glibc 2.x的过程中死了。)

鉴于以下原因,该功能被认为无用:

  • 安全漏洞。静态链接的应用程序甚至不支持libc的升级。如果应用程序在包含lib漏洞的系统上链接,则它将在静态链接的可执行文件中永久保留。

  • 代码膨胀。如果在同一系统上运行许多静态链接的应用程序,则标准库将不会被重用,因为每个应用程序都包含其自己的所有内容副本。(尝试du -sh /usr/lib了解问题的严重程度。)

尝试挖掘10-15年前的LKML和glibc邮件列表档案。我很确定很早以前就已经看到了与LKML相关的内容。

2020-06-02