Linux 静态链接死了?

事实上,Linux 上的 静电干扰 gcc 标志现在已经不起作用了,让我引用 GNU libc 的常见问题解答:

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

{ AJ } NSS (有关详细信息,请键入‘ info Libc“ Name Service Switch”’)不会 正常工作而不分享 新系统允许使用不同的 服务(例如: NIS、档案、数码声音广播、海西) 只要改变一个配置 文件(/etc/nsswitch.conf) 重新连接任何程序 缺点是现在静止了 库需要访问共享的 库。这是处理 通过 GNU C 库透明地。

配置 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。没有开关 因此它是 非常高 推荐使用 没有 - able-static-nss,因为这使得程序在 系统不一致

关于这个事实,现在有什么合理的方法可以在 Linux 上创建一个全功能的静态构建,或者静态链接在 Linux 上已经完全死了吗?我的意思是静态构建:

  • 行为方式和 动态构建(static-nss with 不一致的行为是邪恶的!) ;
  • 工作在 glibc 环境和 Linux 版本的合理变化;
43998 次浏览

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".

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.

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.

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.

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.

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").