【问题标题】:Any downsides to using statically linked applications on Linux?在 Linux 上使用静态链接的应用程序有什么缺点吗?
【发布时间】:2009-05-19 11:46:36
【问题描述】:

我在这里看到了几个关于这个主题的讨论,但想问一下我的特殊情况:

如果我有一些我的应用程序正在使用的第 3 部分库,并且我想将它们链接在一起以便为自己省去 LD_LIBRARY 等的麻烦,那么它在 Linux 上是否有任何缺点,除了更大文件大小?

另外,是否可以只静态链接一些库,而其他(标准 Linux 库)动态链接?

谢谢。

【问题讨论】:

    标签: linux dynamic static linker


    【解决方案1】:

    确实可以动态链接到一些库并静态链接到其他库。

    听起来您真正想做的是动态链接系统库,并静态链接用户可能未安装的非标准库(或者不同用户可能有不同的安装)。

    这是完全合理的。

    静态链接到系统库,尤其是 libc,通常不是一个好主意。

    静态链接不随操作系统提供且不会随您的应用程序分发的库通常是有意义的。

    【讨论】:

    • 嗨。是的,这就是我想要做的。为了使其工作,我需要传递给编译器的标志是什么?问候。
    • 如果您有.a 格式的库(例如libfoo.a),那么您需要做的就是将它们添加到命令行。删除您可能拥有的任何 -lfoo 。所以动态版本: ld -o result my.o -lfoo 会变成: ld -o result my.o /path/to/libfoo.a
    【解决方案2】:

    libc 的某些部分(使用 nsswitch 的部分)需要动态加载库。如果您想生成完全静态的二进制文件,这可能会导致问题。

    将您的第 3 方库静态链接到您的应用程序应该完全没问题。

    【讨论】:

    • 谢谢 - 要链接的标志是 -L 表示动态,-l 表示静态吗?
    • 要静态链接,只需将完整路径添加到 lib*.a 文件。 -L 用于在搜索库时包含某些路径(在链接期间),-l 用于动态链接。
    【解决方案3】:

    静态链接的二进制文件将比使用共享库时更大,但我发现如果我控制所有相关库的分布,则缺点超过了库路径的麻烦。如果您依赖于特定的发行版共享库,那么您别无选择,只能使用动态链接。

    【讨论】:

      【解决方案4】:

      我看到的主要缺点是您的应用程序丢失了任何可能应用于共享库的自动错误修复。另一方面,您不会遇到新的错误。

      【讨论】:

        【解决方案5】:

        静态链接不仅会影响库的文件大小,还会影响应用程序的内存占用和启动时间。无论有多少程序使用动态链接库,它们都会被加载一次。每个使用静态链接库的程序都必须加载一次(因为它们现在是该程序的一部分)。

        【讨论】:

          【解决方案6】:

          要回答您的第二个问题,是的,可以将动态库和静态库链接到同一个应用程序。请注意避免库间依赖关系,这样您就不会遇到库顺序问题。您应该能够以任意顺序列出库。在我工作的地方,我们更喜欢按字母顺序列出。

          编辑:要链接静态库,请使用标志 -lfoo。要将目录添加到库搜索路径,请使用 -L/path/to/libfoo。

          编辑:您不必链接动态库。您的程序可以使用编译器提供的函数在运行时打开动态库,或者您可以在编译时链接它,编译器将解析符号但不将它们包含在二进制文件中。请参阅下面 pjc50 的评论。

          【讨论】:

          • 意思是你只指定两个标志,一个用于静态,一个用于动态,并且在每个标志中,以 ABC 格式列出它们?您使用的标志是什么?
          • 这有点误导——你肯定会链接到动态库,你可以隐式加载它们而不必使用 dlopen()。 -lfoo 将动态链接到 libfoo.so 如果它可以找到它,否则静态链接到 libfoo.a。当它链接到 libfoo.so 时,它不会将代码复制到二进制文件中,它会在文件头中放置一个引用,告诉操作系统运行时链接器在程序运行时加载 libfoo.so。
          • 谢谢,@pjc50。我不知道。
          【解决方案7】:

          静态链接会使您的二进制文件变得庞大,但您不需要在目标运行时环境中拥有该库的共享版本。在开发嵌入式应用程序时尤其如此。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-01-29
            • 1970-01-01
            • 2016-06-29
            • 1970-01-01
            • 1970-01-01
            • 2016-09-19
            • 2012-11-18
            相关资源
            最近更新 更多