如何将多个C/C++库合并为一个?

47

我厌倦了将十个链接库添加到我的项目中,或者要求其中八个来使用我的项目。我想将现有的库如libpng.a、libz.a和libjpeg.a合并成一个单独的.a库文件。这是否可能?那么如何合并.lib库呢?

6个回答

28

您可以使用以下命令从每个库中提取对象文件:

ar x <library name>

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

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

这在所有ar上都不起作用。阅读手册后,我发现早期版本的ar更容易实现: sh4-linux-ar r <existinglib.a> *.o 以将其他符号附加到existinglib.a - Edu Felipe
这也会导致命令行长度的问题。编译 .a/.lib 文件通常用于绕过 WIN32 命令行的 4096 字符限制(无法一次链接或制作太多 .o)。 - whitey04
3
请注意,如果你的两个库中包含有相同名称的成员,那么简单地将库解压到目录中然后重新打包的方法将会失败---其中一个成员将会丢失。你需要重命名一个成员以避免冲突。 - David Given

10
在Linux上,可以使用MinGW或Cygwin与GNU工具链一起使用:

MinGWCygwin

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上,使用Microsoft Visual C++工具链:

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

请您详细介绍一下MSCV工具链的步骤,谢谢。 - javaLover
1
@javaLover,我很想这么做,但抱歉我现在没有任何Windows电脑。 - Star Brilliant
“保持liba.alibb.a的存在”是什么意思?你能详细说明一下吗? - Peter Mortensen

9
在类Unix系统上,ld和ar工具可以实现此功能。请查看http://en.wikipedia.org/wiki/Ar_(Unix)或通过Linux操作系统的man手册或Google搜索进行查找,例如“Unix man ar”。
请注意,最好链接到共享(动态)库。这将向您的可执行文件添加依赖项,但它将显着减小其大小,特别是如果您正在编写图形应用程序。

1
在图形应用程序中,为什么较小的图像尺寸更好? - ds-bos-msk
1
通常情况下,图像尺寸越小越好。图形库(如xlib等)往往非常庞大,因此如果静态链接,则会生成非常大的可执行文件。 - Avner
哦,你是指GUI应用程序啊。我以为你是在说图形方面的,比如带有GPU着色器等的3D引擎... - ds-bos-msk
是的,我指的是像GUI库这样的库。 - Avner

0

我不确定如何将它们物理上合并为单个文件,但是您可以使用某种抽象来仅包含一个“AllMyLibs.a/h”,其中包含您想要的所有内容。您还可以将其放置在编译器搜索库的位置,以便任何项目都可以使用。


0
也许我有误解,但是如果最终用户代码直接调用库,您难道不只需要发送库吗? 如果所有对JPEG方法的访问等都来自您静态库中的代码,则只需将库链接到您的库即可。

I.e.,

---------------------
| End-user EXE file |
---------------------
      |
      | 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,例如,那么正如上面提到的,这将是使用动态模块的情况。


18
不,当你创建“你的静态库.a”时,不需要进行链接。链接只在创建最终可执行文件时才会执行。这正是提问的原因。 - Trent
4
@Greg; Trent是正确的。创建一个库只是使用带有符号表的归档工具(ar)将目标文件放在一起。没有编译器(cc)或链接器(ld),只有归档工具(ar)。 - whitey04
1
我知道这是一个旧的讨论,但最近我也遇到了同样的问题,我必须支持 Trent。我构建了一个静态库,其中调用了 glib(也是一个静态库)。但是我的库文件中没有包含来自 glib 的任何内容,这些调用仅被留作未解决的。如果您尝试链接到我的库而不链接到 glib,这些未解决的调用会导致链接器失败。我可以使用 arglib 和我的库打包成一个文件,但这几乎肯定是一个坏主意(最终会为某人导致重复定义),并且会使我的库变得非常庞大。 - brianmearns
我同意。Trent是对的。我知道这是几年前的事情了,但我相信当时我是在考虑DLL而不是静态库。尽管如此,我仍然为我的艺术作品感到自豪 :) - Greg Whitfield
这样做的问题在于,在您的最终用户exe中,您将不得不明确链接到其下面的所有静态库,因此包括libjpeg、libz和libpng。 实际上,这正是我遇到的应用程序,而且在我的情况下有更多的图像格式,所以我将有一个非常长的链接列表。 - ds-bos-msk
显示剩余2条评论

-1
将几个第三方库合并成一个可能会为您带来更多问题,例如,如果其中两个库定义了一个常见的符号,而您的程序没有使用该符号。现在,您必须在合并库之前提取所有(或除一个之外的所有)常见符号的实例。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接