Linux 静态链接已死?
事实上,-static gcc 标志在 Linux 上现在不起作用。让我引用 GNU libc FAQ 中的内容:
2.22。即使静态链接的程序也需要一些共享库 这对我来说是不能接受的。什么 我可以做什么吗?
{AJ} NSS(有关详细信息,只需输入“info libc“名称服务开关”') 不会 无需共享即可正常工作 图书馆。 NSS 允许使用不同的 服务(例如 NIS、文件、数据库、hesiod) 只需更改一项配置 文件(/etc/nsswitch.conf)不带 重新链接任何程序。唯一的 缺点是现在是静态的 库需要访问共享 图书馆。这是处理的 由 GNU C 库透明地执行。
解决方案是配置 glibc --启用静态 nss。在这种情况下,您可以创建一个静态二进制文件 仅使用服务 DNS 和文件 (为此更改/etc/nsswitch.conf)。 您需要明确链接 所有这些服务。例如:
gcc -static test-netdb.c -o test-netdb \ -Wl,--开始组 -lc -lnss_files -lnss_dns -lresolv -Wl,--结束组
这种方法的问题是 你必须链接每个静态 使用 NSS 例程的程序 所有这些图书馆。
{UD} 事实上,我们不能再说 libc 是用这个选项编译的 正在使用 NSS。没有开关 不再了。因此它高度 建议不使用 --enable-static-nss 因为这使得程序的行为 系统不一致。
事实上,现在是否有任何合理的方法可以在 Linux 上创建功能齐全的静态构建,或者静态链接在 Linux 上完全失效了?我的意思是静态构建:
- 行为方式与 动态构建(static-nss 与 不一致的行为是邪恶的!);
- 适用于 glibc 环境和 Linux 版本的合理变化;
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;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
静态链接又回来了!
pkgsStatic
包set 可以提供各种静态链接的可执行文件)。Static linking is back on the rise!
pkgsStatic
package set can provide all kinds of statically linked executables).我不知道在哪里可以找到历史参考资料,但是,是的,静态链接在 GNU 系统上已经失效了。 (我相信它在从 libc4/libc5 到 libc6/glibc 2.x 的过渡过程中消失了。)
鉴于以下原因,该功能被认为毫无用处:
安全漏洞。静态链接的应用程序甚至不支持 libc 的升级。如果应用程序链接到包含库漏洞的系统上,那么它将在静态链接的可执行文件中永久存在。
代码膨胀。如果许多静态链接的应用程序在同一系统上运行,则标准库将不会被重用,因为每个应用程序都包含自己的所有内容的副本。 (尝试 du -sh /usr/lib 来了解问题的严重程度。)
尝试挖掘 10-15 年前的 LKML 和 glibc 邮件列表档案。我很确定很久以前我就在 LKML 上看到过一些相关的东西。
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 世界中似乎不太受欢迎。这是我的看法。
没有看到静态链接吸引力的人通常在内核和较低级别操作系统领域工作。许多 *nix 库开发人员一生都在处理不可避免的问题,试图将一百个不断变化的库链接在一起,这是他们每天都会做的任务。如果您想了解它们可以轻松执行的后空翻,请查看自动工具。
但不应指望其他人将大部分时间花在这上面。静态链接将使您在避免库流失方面走得更远。开发人员可以根据软件的时间表升级软件的依赖项,而不是在新的库版本出现时被迫这样做。这对于具有复杂用户界面的面向用户的应用程序非常重要,这些应用程序需要控制它们不可避免地依赖的许多较低级别库的流量。这就是为什么我永远是静态链接的粉丝。如果您可以静态链接交叉编译的可移植 C 和 C++ 代码,那么您几乎已经让世界变得随心所欲,因为您可以更快地将复杂的软件交付给世界上各种不断增长的设备。
从其他角度来看,有很多不同意的地方,开源软件允许所有这些都是很好的。
Static linking doesn't seem to get much love in the Linux world. Here's my take.
People who do not see the appeal of static linking typically work in the realm of the kernel and lower-level operating system. Many *nix library developers have spent a lifetime dealing with the inevitable issues of trying to link a hundred ever-changing libraries together, a task they do every day. Take a look at autotools if you ever want to know the backflips they are comfortable performing.
But everyone else should not be expected to spend most of their time on this. Static linking will take you a long way towards being buffered from library churn. The developer can upgrade her software's dependencies according to the software's schedule, rather than being forced to do it the moment new library versions appear. This is important for user-facing applications with complex user interfaces that need to control the flux of the many lower-level libraries upon which they inevitably depend. And that's why I will always be a fan of static linking. If you can statically link cross-compiled portable C and C++ code, you have pretty much made the world your oyster, as you can more quickly deliver complex software to a wide range of the world's ever-growing devices.
There's lots to disagree with there, from other perspectives, and it's nice that open source software allows for them all.
仅仅因为您必须动态链接到 NSS 服务并不意味着您不能静态链接到任何其他库。常见问题解答的全部内容是,即使是“静态”链接的程序也有一些动态链接库。这并不是说静态链接“不可能”或“不起作用”。
Just because you have to dynamically link to the NSS service doesn't mean you can't statically link to any other library. All that FAQ is saying is that even "statically" linked programs have some dynamically-linked libraries. It's not saying that static linking is "impossible" or that it "doesn't work".
添加其他答案:
由于其他答案中所述的原因,不建议大多数 Linux 发行版使用它,但实际上有一些发行版是专门为运行静态链接的二进制文件而制作的
来自 stali 描述:
静态链接也有助于减少依赖性。
您可以在这个关于静态链接与动态链接的问题中阅读更多相关信息。
Adding on other answers:
Due to the reasons said in the other answers, it's not recommended for most of Linux distributions, but there are actually distributions that are made specifically to run statically linked binaries:
From stali description:
Statically linking also helps to for dependency reduction.
You can read more about it in this question about static vs dynamic linking.
我认为这非常烦人,并且我认为称某个功能“无用”是傲慢的,因为它在处理某些用例时存在问题。 glibc 方法的最大问题是它硬编码了系统库(gconv 和 nss)的路径,因此当人们尝试在不同于其构建版本的 Linux 发行版上运行静态二进制文件时,它就会崩溃。
无论如何,您可以通过将 GCONV_PATH 设置为指向适当的位置来解决 gconv 问题,这使我能够获取在 Ubuntu 上构建的二进制文件并在 Red Hat 上运行它们。
I think this is very annoying, and I think it is arrogant to call a feature "useless" because it has problems dealing with certain use cases. The biggest problem with the glibc approach is that it hard-codes paths to system libraries (gconv as well as nss), and thus it breaks when people try to run a static binary on a Linux distribution different from the one it was built for.
Anyway, you can work around the gconv issue by setting GCONV_PATH to point to the appropriate location, this allowed me to take binaries built on Ubuntu and run them on Red Hat.