Linux 静态链接已死?

发布于 2024-09-13 10:47:48 字数 1042 浏览 7 评论 0原文

事实上,-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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

薄凉少年不暖心 2024-09-20 10:47:49

静态链接又回来了!

  • 莱纳斯·托瓦尔兹 支持静态链接,并对 Linux 发行版中的静态链接数量表示担忧(另请参阅此讨论)。
  • 许多(大多数?)Go 编程语言可执行文件都是静态链接的。
    • 增强的可移植性和向后兼容性是它们受欢迎的原因之一。
  • 其他编程语言也有类似的努力来使静态链接变得非常容易,例如:
    • Haskell(我正在努力努力
    • Zig(请参阅此处了解详细信息)
  • 可配置的 Linux 发行版 / 软件包集,例如 NixOS / nixpkgs 使得静态链接大部分包成为可能(例如,它的 pkgsStatic 包set 可以提供各种静态链接的可执行文件)。
  • 静态链接可以在链接时更好地消除未使用的代码,从而使可执行文件更小。
  • musl 这样的 libc 使静态链接变得简单且正确。
  • 一些大型软件行业领导者对此表示同意。例如,Google 正在编写针对静态链接的新 libc“支持静态非 PIE 和静态 PIE 链接”“我们目前不打算投资动态加载和链接支持”)。

Static linking is back on the rise!

  • Linus Torvalds is in support of static linking, and expressed concern about the amount of static linking in Linux distributions (see also this discussion).
  • Many (most?) Go programming language executables are statically linked.
    • The increased portability and backward compatibility is one reason for them being popular.
  • Other programming languages have similar efforts to make static linking really easy, for example:
    • Haskell (I am working on this effort)
    • Zig (see here for details)
  • Configurable Linux distributions / package sets like NixOS / nixpkgs make it possible to link a large fraction of their packages statically (for example, its pkgsStatic package set can provide all kinds of statically linked executables).
  • Static linking can result in better unused-code elimination at link time, making executables smaller.
  • libcs like musl make static linking easy and correct.
  • Some big software industry leaders agree on this. For example Google is writing new libc targeted at static linking ("support static non-PIE and static-PIE linking", "we do not intend to invest in at this point [in] dynamic loading and linking support").
十雾 2024-09-20 10:47:49

事实上,现在有没有合理的方法可以在 Linux 上创建功能齐全的静态构建,或者静态链接在 Linux 上完全失效了?

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

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

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

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

尝试挖掘 10-15 年前的 LKML 和 glibc 邮件列表档案。我很确定很久以前我就在 LKML 上看到过一些相关的东西。

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.

榆西 2024-09-20 10:47:49

静态链接在 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.

百合的盛世恋 2024-09-20 10:47:49

仅仅因为您必须动态链接到 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".

断爱 2024-09-20 10:47:49

添加其他答案:

由于其他答案中所述的原因,不建议大多数 Linux 发行版使用它,但实际上有一些发行版是专门为运行静态链接的二进制文件而制作的

来自 stali 描述:

static linux 基于手工挑选的最佳工具集合
对于每个任务和每个工具都静态链接(包括一些X
st、surf、dwm、dmenu 等客户端),

它还旨在通过避免 glibc 来减少二进制大小
以及其他可能的臃肿的 GNU 库(早期实验表明
静态链接的二进制文件通常小于它们的
动态链接的 glibc 对应物!!!)。注意,这已经差不多了
与 Ulrich Drepper 对静态链接的看法相反。

由于静态链接的二进制文件启动速度更快的副作用,
该发行版还以性能提升为目标。

静态链接也有助于减少依赖性。

您可以在这个关于静态链接与动态链接的问题中阅读更多相关信息。

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:

static linux is based on a hand selected collection of the best tools
for each task and each tool being statically linked (including some X
clients such as st, surf, dwm, dmenu),

It also targets binary size reduction through the avoidance of glibc
and other bloated GNU libraries where possible (early experiments show
that statically linked binaries are usually smaller than their
dynamically linked glibc counterparts!!!). Note, this is pretty much
contrary to what Ulrich Drepper reckons about static linking.

Due to the side-benefit that statically linked binaries start faster,
the distribution also targets performance gains.

Statically linking also helps to for dependency reduction.

You can read more about it in this question about static vs dynamic linking.

骑趴 2024-09-20 10:47:48

我认为这非常烦人,并且我认为称某个功能“无用”是傲慢的,因为它在处理某些用例时存在问题。 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文