我想将静态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
标记为内部(t
和s
标记)的所有其他符号。
如何将符号保留在外?
更新:
看起来这可能是类似的问题:Export an `OBJC_CLASS` from one static lib as part of another
问题是静态库中的符号被导出为private_extern
,并且无法将它们保存在动态库中。
答案 0 :(得分: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。