【问题标题】:Linking static libraries, that share another static library链接静态库,共享另一个静态库
【发布时间】:2012-07-29 19:49:57
【问题描述】:

我目前有一个 Xcode 项目,用于非常大的代码库,我将其称为 Project X,我将其划分为一堆子项目(Projects A、B , C )。

到目前为止,这些项目中的每一个都可以自行编译。它们都产生静态库。 Project BProject C 依赖于 Project A 生成的静态库才能构建。

我有另一个 xcode 项目,Project Z,它需要 Projects B 和 C 生成的静态库。问题就在这里。当 Project Z 进入链接器阶段时,事情就会爆发 - 在 Projects B 和 C 的库中发现重复的符号,因为它们最初在 Project 中链接的代码一个

我对静态库的世界还很陌生,我不确定如何推进 Project Z,或者如何修改其他项目以便它们链接到相同的 Project A 库。我有一种感觉,这是不可能的。我在这里有什么选择?

编辑:

我应该澄清一下,Project BProject C 需要构建到单独的静态库中,因为有些客户端只需要其中一个。

另外,我在 OSX 和 iOS 平台上都遇到了这种困境。

我意识到我可以通过将项目构建为动态库来解决 OSX 上的这个问题。但是,我不想这样做,它仍然让我在 iOS 上遇到同样的问题。

【问题讨论】:

    标签: xcode linker static-libraries


    【解决方案1】:

    静态库不应包含其他静态库(或一般的第三方代码)。静态库只是粘合在一起的一束 .o 文件。所以如果你有多个相同信息的副本,它就会爆炸。

    每个静态库都应该有自己的代码。最终的应用程序负责将所有需要的库链接在一起(包括库所需的库)。这样一来,每个链接的事物都只有一个副本。

    【讨论】:

    • 是的,你说得对。我通过简单地不将项目 B 和项目 C 链接到项目 A 解决了这个问题。项目 B 和 C 仍然将项目 A 引用为依赖项,因此它们能够构建得很好。由于客户将始终将项目 A 与这些项目一起包括在内,因此可以找到所有符号并且一切正常。
    • @Jeff 您如何使 A 成为“依赖项”,以便其他人可以构建,而实际上并没有在他们的构建中链接到(包括)A?
    • @Rob 我注意到,如果我在 Xcode 中构建一个静态库,该库仅包含另一个库的标头,但不链接到另一个库的二进制文件,则构建完成得很好。如果我改为使用实际程序项目(而不是库)执行此操作,则链接阶段存在未定义的定义(错误)。我假设当您构建库时,“跳过”链接阶段的这一部分是正常的,而实际程序在构建时会进行额外的链接检查,对吗? (如果编译器被指示构建一个库,那这就是编译器实际上正在做的事情吗?)
    • @johnbakers 静态库只是未链接的.o 文件的集合,所以是的,这是意料之中的。 .h 文件只是承诺在链接时会有可用的符号。它们通常不会生成任何自己的代码或分配(它们有可能这样做,但如果它们在 C 或 ObjC 中这样做通常是错误的;C++ 是另一种动物)。构建静态库不会“跳过链接阶段的这一部分”。构建静态库时没有链接阶段。您编译到.o,然后将它们粘合在一起(存档)到.a
    • @focs 正确。您必须在文档中告诉他们。这不是一个可修复的问题。没有依赖管理器(CocoaPods、Carthage、SPM),就没有简单的依赖管理解决方案。也就是说,您不需要 C/ObjC 中的完美版本匹配。类似的版本仍然会成功链接。 (显然,如果您依赖特定版本的行为,这可能会带来问题;这甚至无法通过框架解决。)
    【解决方案2】:

    这听起来就像是CoacoaPods 就是为了解决这个问题而创建的。如果您为这些项目中的每一个定义 pod,那么 Z 应该能够在不引入重复符号的情况下确定并链接到其所有依赖项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多