4

我想将静态 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并且没有办法将它们保存在动态库中。

4

1 回答 1

2

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。

于 2017-05-12T14:14:06.520 回答