为什么静态链接没有被更多地使用?
我了解动态链接的好处(旧代码可以自动利用库升级,它更节省空间),但它肯定有缺点,特别是在异构 Linux 生态系统中。这使得分发“正常工作”的与发行版无关的二进制文件变得困难,并且使先前工作的程序更有可能由于破坏向后兼容性或在共享库中引入回归的系统升级而中断。
鉴于这些缺点,为什么动态链接似乎受到如此普遍的青睐?为什么找到静态链接的、与发行版无关的 Linux 二进制文件如此困难,即使对于小型应用程序也是如此?
I understand the benefits of dynamic linking (old code can take advantage of library upgrades automatically, it's more space efficient), but it definitely has downsides, especially in the heterogeneous Linux ecosystem. It makes it difficult to distribute a distribution-agnostic binary that "just works" and makes a previously working program more likely to break due to a system upgrade that breaks backwards compatibility or introduces regressions into a shared library.
Given these disadvantages, why does dynamic linking seem to be so universally preferred? Why is it so hard to find statically linked, distribution-agnostic Linux binaries, even for small applications?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
主要有以下三个原因:
您还应该记住,Linux(而非 Android)软件生态是完全基于源代码的。如果您正在运输二进制文件并且您不是分发供应商,那么您就做错了。
There are three big reasons:
dlopen
. (This means that static linkage to anything else is less worthwhile, because you can't get a totally static binary without replacing the C library.)You should also keep in mind that the Linux-not-Android software ecology is entirely source-based. If you are shipping binaries and you're not a distribution vendor you are Doing It Wrong.
我们更喜欢动态链接有几个原因:
许可。这是 LGPL 的一个特殊问题,尽管还有其他具有类似限制的许可证。
基本上,我向您发送针对 LGPL libfoo.so.* 构建的二进制文件,甚至为您提供该库的二进制文件是合法的。我有各种职责,例如响应 LGPL 库源代码的请求,但这里重要的是我不必也向您提供我的程序的源代码。由于 glibc 是 LGPL,并且 Linux 机器上的几乎每个二进制文件都链接到它,因此默认情况下仅此一项就会强制动态链接。
带宽成本。人们喜欢说带宽是免费的,但这只是原则上的。在许多实际情况下,带宽仍然很重要。
我公司基于 C++ 的主要系统打包成大约 4 MB RPM,在大多数客户站点上通过慢速 DSL 上行链路上传需要几分钟。我们仍然有一些客户只能通过调制解调器访问,对于这些客户来说,上传就是“启动它,然后去吃午饭”。如果我们发送静态二进制文件,这些包会大得多。我们的系统由多个协作程序组成,其中大多数都链接到同一组动态库,因此 RPM 将包含相同共享代码的冗余副本。压缩可以挤出一些内容,但为什么每次升级都要一次又一次地发送它呢?
管理。我们链接的许多库都是操作系统发行版的一部分,因此我们可以独立于我们的程序获得这些库的免费更新。我们不必管理它。
我们确实单独提供了一些不属于操作系统的库,但它们的更改频率比我们的代码要少得多。通常,这些是在我们构建服务器时安装在系统上的,然后再也不会更新。这是因为我们通常对稳定性比这些库的新功能更感兴趣。只要它们在工作,我们就不会碰它们。
There are several reasons we prefer dynamic linkage:
Licensing. This is a particular issue with the LGPL, though there are other licenses with similar strictures.
Basically, it's legal for me to send you a binary built against LGPL libfoo.so.*, and even to give you a binary for that library. I have a various responsibilities, such as responding to requests for the source for the LGPL'd library, but the important thing here is that I don't have to give you the source for my program, too. Since glibc is LGPL and almost every binary on a Linux box is linked to it, that alone will force dynamic linkage by default.
Bandwidth costs. People like to say bandwidth is free, but that's true only in principle. In many practical cases, bandwidth still matters.
My company's main C++-based system packs up into a ~4 MB RPM, which takes a few minutes to upload over the slow DSL uplinks at most of our customers' sites. We still have some customers only accessible via modem, too, and for those an upload is a matter of "start it, then go to lunch." If we were shipping static binaries, these packages would be much larger. Our system is composed of several cooperating programs, most of which are linked to the same set of dynamic libraries, so the RPM would contain redundant copies of the same shared code. Compression can squeeze some of that out, but why keep shipping it again and again for each upgrade?
Management. Many of the libraries we link against are part of the OS distro, so we get free updates to those libraries independent from our program. We don't have to manage it.
We do separately ship some libraries which aren't part of the OS, but they have to change much less often than our code does. Typically, these are installed on the system when we build the server, then never updated again. This is because we are most often more interested in stability than new features from these libraries. As long as they're working, we don't touch them.