【问题标题】:Link against two versions of the same library (same symbols)链接同一个库的两个版本(相同的符号)
【发布时间】:2014-12-11 10:54:54
【问题描述】:

我正在开发一个 iOS 应用程序并希望链接到一个特定的库。然而,同一个库的分叉/旧版本(带有冲突符号)已静态链接到我也在使用的框架中。因为框架引入的版本是分叉和过时的,所以我想以某种方式将新库用于我的目的,并允许框架继续使用旧/分叉版本,所有这些都在一个 iOS 中二进制。

我无法控制库的旧版本/分叉版本,但我可以随意编译新版本。

我可以做些什么来自动为新版本库中的符号添加前缀/命名空间,以便我可以在不与旧版本中的符号冲突的情况下使用它们?

【问题讨论】:

  • 您可以将使用静态库的代码移动到它自己的框架中,从而有效地包装静态库代码,重点关注您自己的需求。这绝对可以避免任何符号冲突。
  • @Benjamin 您找到解决方案了吗?我很乐意提出一些建议。
  • @raurora 实际上,我能够按照 Droppy 的建议做一些事情。但是,这是一个有趣的问题,所以如果您有其他建议要发布,我很乐意听到。
  • @BenjaminDobell 如果 Droppy 的解决方案对您有用(没有错误),您可以在下面发布答案 - stackoverflow.com/help/self-answer

标签: ios clang static-linking


【解决方案1】:

结合以下两个堆栈溢出帖子的信息:

通过查看PLCrashReporter,我得出以下结论:

  1. 在 XCode 中新建一个 Cocoa Touch 静态库“Wrapper”项目。

  2. 将新静态库的“Mach-O Type”改为“Relocatable Object File”。

  3. 选择您不想调试的复制库的哪个版本,即您将不得不为复制库的一个副本丢弃符号,因此您将无法调试它。

    在我的例子中,我选择丢弃带有旧版本库/符号的预编译依赖项的符号。我做出这个决定是因为预编译的依赖来自第三方,而且它没有调试符号。

  4. 在新的 Cocoa Touch“包装器”项目中启用“执行单个对象预链接”使用您选择不使用的库/依赖项的相对路径填充“预链接库”可以调试。

  5. 我怀疑这一步实际上并不是必需的,但我这样做是因为它似乎使我的意图更加明确(关于构建设置)

    在“Wrapper”项目中将“默认隐藏的符号”设置为“是”,然后标记您打算导出的任何 Objective-C 类、C++ 方法/类等:

    属性((visibility("default")))

  6. 在“Wrapper”项目中,将“Deployment Preprocessing”设置为“Yes”,将“Strip Style”设置为“Non-Global Symbols” (在我们的例子中,这会导致 Objective -C 库中的类别被错误地省略).

  7. 1234563你原来的项目)。
  8. 这一步对我来说很关键 - 添加 Exported Symbols File 并在其中准确指定要导出的符号(即上面提到的小 API)。将“Exported Symbols File”构建设置设置为该文件的相对路径(同样在“Wrapper”项目中)。

  9. 转到原始项目,从“将二进制文件与库链接”构建阶段删除您刚刚为其创建包装器 API 的依赖项,并将其替换为新的包装器库。您还需要更新项目中的任何代码以使用新的包装 API。

  10. 如果您还没有,请将新版本的库(以前会导致符号冲突)添加到主项目,并照常使用这些 API。

【讨论】:

    猜你喜欢
    • 2011-09-26
    • 1970-01-01
    • 2016-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多