【问题标题】:How to combine several C/C++ libraries into one?如何将多个 C/C++ 库合并为一个?
【发布时间】:2010-09-06 00:02:41
【问题描述】:

我已经厌倦了在我的项目中添加十个链接库,或者需要其中八个来使用我自己的。我想采用现有的库,如 libpng.a、libz.a、libjpeg.a,并将它们组合成一个 .a 库。那可能吗?合并 .lib 库怎么样?

【问题讨论】:

    标签: c++ c archive


    【解决方案1】:

    在 Linux 或 MinGW 或 Cygwin 上,使用 GNU 工具链:

    ar -M <<EOM
        CREATE libab.a
        ADDLIB liba.a
        ADDLIB libb.a
        SAVE
        END
    EOM
    ranlib libab.a
    

    或者如果你可以保持liba.alibb.a的存在:

    ar crsT libab.a liba.a libb.a
    

    在 Windows 上,使用 MSVC 工具链:

    lib.exe /OUT:libab.lib liba.lib libb.lib
    

    【讨论】:

    • 您能否详细说明 MSCV 工具链的详细信息?谢谢。
    • @javaLover 我想要,但很抱歉我现在没有任何 Windows PC。
    【解决方案2】:

    我不确定如何将它们物理地组合到一个文件中,但是您可以使用某种抽象并只包含一个“AllMyLibs.a/h”,而该“AllMyLibs.a/h”又包含您想要的所有内容。你也可以把它放在你的编译器搜索库的位置,所以它适用于任何项目。

    附: - 出于好奇,您为什么不喜欢包含单个库?

    【讨论】:

      【解决方案3】:

      在类 Unix 系统上,ld 和 ar 实用程序可以做到这一点。查看 http://en.wikipedia.org/wiki/Ar_(Unix) 或在任何 linux 机器上或通过 google 查找手册页,例如“unix man ar”。

      请注意,链接到共享(动态)库可能会更好。这会给您的可执行文件添加一个依赖项,但会显着减小其大小,尤其是在您编写图形应用程序时。

      【讨论】:

      • 为什么在图形应用程序中较小的图像尺寸更好?
      • 较小的图像尺寸通常更好。图形库(xlib 等)往往非常大,因此如果静态链接,则会生成非常大的可执行文件。
      • 哦,你的意思是 GUI 应用程序。我以为你指的是带有 GPU 着色器和其他东西的 3D 引擎中的图形......
      • 是的,我指的是类似于库的 GUI。
      【解决方案4】:

      将多个第三方库合并为一个可能会给您带来更多问题 - 例如,如果其中两个库定义了您的程序不使用的公共符号。现在,您必须在组合库之前提取公共符号的所有(或唯一一个)实例。

      【讨论】:

        【解决方案5】:

        也许我理解错了,但是如果最终用户代码直接调用它们,您是否只需要发送这些库?如果对 Jpeg 方法等的所有访问都来自您的静态库中的代码,那么只需将这些库链接到您的库中。

        ----------------
        | End-user exe |
        ----------------
              |
              | makes calls to
              |
              v
         --------------------
         | Your static lib.a | 
         --------------------
                 | makes calls to and links
                 v
             ------------------------------------ .....
             |                    |         |
          -------------    -------- ---------- 
          | libjpeg.a |    |libz.a| |libpng.a|
          -------------    -------- ----------
        

        也就是说,如果最终代码需要直接调用 libz.a、libpng.a 等,这只是一个问题。

        例如,如果应用程序代码有调用 libz.a 的合法需求,那么如上所述,这就是使用动态模块的情况。

        PS:我可以获得艺术家徽章吗? :)

        【讨论】:

        • 不,当你创建“你的静态 lib.a”时你没有链接。仅在创建最终可执行文件时才执行链接。这正是提出这个问题的原因。
        • 对不起,特伦特你不正确。链接适用于库,而不仅仅是 EXE。
        • @Greg;特伦特是对的。创建库只是将目标文件放在带有符号表的存档中。没有编译器 (cc) 或链接器 (ld),只有归档工具 (ar)。
        • @whitey04:严格来说,你是正确的或当然的。但我说的是使用库作为其他库的输入的更宽松的意义上。至少,我最初是虽然我对特伦特的评论可能与此相矛盾——毕竟他们之间有几个月的时间......也许我应该在我的图表中说“打电话和参考”。我不愿引用维基百科——我们知道这有多可靠;)——但请查看此页面上的图片以了解我的驾驶情况——en.wikipedia.org/wiki/Linker_(computing)
        • 我知道这是一个古老的讨论,但我最近遇到了同样的事情,我不得不和特伦特一起去。我构建了一个静态库,它调用glib(也是一个静态库)。但是 glib 中的任何内容都没有包含在我的库文件中,这些调用只是未解决。如果您尝试链接到我的库而不链接到glib,这些未解决的调用会导致链接器失败。我可以使用arglib 和我的库打包成一个,但这几乎可以肯定是个坏主意(最终会导致某人重复定义),并且会使我的库变得庞大。
        【解决方案6】:

        你可以从每个库中提取目标文件

        ar x <library name>
        

        然后将它们全部合并到一个新的库中

        ar cs <new library name> <list each extracted object file>
        

        【讨论】:

        • 这不适用于所有 ar。阅读手册我发现 ar 的早期版本更容易做到:sh4-linux-ar r &lt;existinglib.a&gt; *.o 将其他符号附加到existinglib.a
        • 这也会导致命令行长度问题。编译 .a/.lib 文件通常用于绕过命令行上 4096 个字符的 WIN32 限制(一次不能有太多 .o 用于链接或制作库)。
        • 请注意,如果您的两个库包含具有相同名称的成员,那么 unpack-libraries-into-directory-and-repack 的天真方法将失败 --- 成员将是丢失。您需要重命名其中一个成员以避免冲突。
        猜你喜欢
        • 1970-01-01
        • 2017-01-11
        • 1970-01-01
        • 2022-01-12
        • 2014-05-15
        • 1970-01-01
        • 1970-01-01
        • 2021-01-10
        • 1970-01-01
        相关资源
        最近更新 更多