【问题标题】:Converting static framework to dynamic将静态框架转换为动态
【发布时间】:2017-09-22 20:39:05
【问题描述】:

我想将静态 iOS 框架 (https://github.com/comScore/ComScore-iOS-watchOS-tvOS/tree/master/ComScore/iOS) 转换为动态。

> clang -arch x86_64 -dynamiclib -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.3.sdk -lc++ -F . -framework ComScore -ObjC -o ComScoreDynamic

此命令成功,但是符号可见性存在问题。

当我在原始框架中检查符号时,大约有 4k 个公共符号:

> nm -gU ComScore.framework/ComScore | wc -l 4387

在动态版本中只有极少数:

nm -gU ComScoreDynamic
0000000000114af8 S _OBJC_CLASS_$_SCORCommonUtils 0000000000114940 S _OBJC_CLASS_$_SCORCrossPublisherIdSourceValue 0000000000114a08 S _OBJC_CLASS_$_SCORHTTP 0000000000114990 S _OBJC_CLASS_$_SCORHelper 0000000000114aa8 S _OBJC_CLASS_$_SCORObfuscation 0000000000114a80 S _OBJC_CLASS_$_SCORReachability 0000000000114918 S _OBJC_CLASS_$_SCORUniqueId 0000000000114b20 S _OBJC_METACLASS_$_SCORCommonUtils 00000000001149e0 S _OBJC_METACLASS_$_SCORCrossPublisherIdSourceValue 0000000000114a30 S _OBJC_METACLASS_$_SCORHTTP 0000000000114968 S _OBJC_METACLASS_$_SCORHelper 0000000000114ad0 S _OBJC_METACLASS_$_SCORObfuscation 0000000000114a58 S _OBJC_METACLASS_$_SCORReachability 00000000001149b8 S _OBJC_METACLASS_$_SCORUniqueId 00000000001166b0 D __ZTINSt3__117bad_function_callE 00000000000d5d60 S __ZTSNSt3__117bad_function_callE

标记为内部的所有其他符号(ts 标记)。

如何将符号保持在外部?

更新:

看起来这可能是类似的问题:Export an `OBJC_CLASS` from one static lib as part of another

问题是静态库中的符号导出为private_extern,无法将它们保存在动态库中。

【问题讨论】:

  • 您不需要将库中的所有内容都设为外部。使用模块导出制作适当的动态 .framework,例如 nsomar.com/modular-framework-creating-and-using-them
  • 感谢您的回复!据我所知,module.map 只影响编译时间,我在链接阶段有一个问题。如果我将创建自定义模块映射,它会影响生成的库吗?此外,我在常规动态框架的 Xcode 链接命令中看不到对模块映射的任何引用。
  • 如您所见,符号没有被剥离,因此 ObjC 运行时会找到它们。为什么你认为这是一个问题?你如何使用动态库?
  • 在将此动态库链接到我的应用程序时收到错误消息:Undefined symbols for architecture armv7: "_OBJC_CLASS_$_SCORReducedRequirementsStreamingAnalytics 在原始库中,此符号被标记为外部:---------------- D _OBJC_CLASS_$_SCORReducedRequirementsStreamingAnalytics 并且在动态中是内部的:000000000011aac0 s _OBJC_CLASS_$_SCORReducedRequirementsStreamingAnalytics
  • 所以类名仍然需要是外部的。这很有趣。

标签: xcode clang ld comscore


【解决方案1】:

comScore 框架中的公共符号标记为private external。这可以通过nm 实用程序和查找 SCORAnalytics 类来查看:

nm -m ComScore/iOS/ComScore.framework/Versions/A/ComScore  |grep _OBJC_CLASS_\$_SCORAnalytics

显示:

---------------- (LTO,DATA) private external _OBJC_CLASS_$_SCORAnalytics

这意味着符号只能链接一次。当 Cocoapods 为辅助(“传递”)依赖项执行预链接时,这些符号会丢失它们的 extern 属性。这里的想法是防止依赖项中的公共符号泄漏到另一个库的公共符号中。问题是,对于 Swift 项目,直到最终的应用链接才完全解决;到那时,它们不再可用。

真正的问题是 comScore 库是一个静态框架。最好的解决方案是 comScore 将其作为动态框架发布,但仅 iOS 8 及更高版本支持; comScore 一直坚持支持到 iOS 6。我知道。

目前,我的解决方案是将 comScore 框架直接包含在我们的 Cocoapod 中,并在 Podspec 中出售,使其能够与 Obj-C 和 Swift 项目一起使用。缺点是每次 comScore 发布新版本时,我都必须手动更新我们的 Cocoapod。如果另一个 pod 包含 comScore,也会出现符号冲突,但由于我们的 pod 是一个记录到多个后端的指标聚合器,它可能是唯一使用的指标组件。 YMMV。

【讨论】:

    猜你喜欢
    • 2013-05-14
    • 2011-02-16
    • 1970-01-01
    • 2021-10-03
    • 2013-06-24
    • 1970-01-01
    • 2012-10-22
    • 2019-10-30
    • 2011-02-04
    相关资源
    最近更新 更多