使用Cocoapods构build静态库时,防止出现重复的符号

虽然我已经看到了许多与Cocoapods和静态库有关的问题,但是他们中的大多数人似乎都认为你最终将拥有一个单独的工作空间与静态库和最终目标应用程序。

在我的情况下,我正在build立一个静态库。 更具体地说,我正在窃听一个MyLib.framework供用户使用。 我真的想用Cocoapodspipe理MyLib.framework的依赖关系,但是当我的库的使用者使用Cocoapods时,它创造了许多痛点。

例如,我的图书馆有我用Cocoapodspipe理的AFNetworking依赖项。 当我build立我的图书馆,它链接在libPods.a其中包括AFNetworking,以及一些“虚拟”文件/对象。 如果我的框架的用户也使用Cocoapods来构build他们的应用程序,他们会看到如下所示:

duplicate symbol _OBJC_METACLASS_$_PodsDummy_Pods in: /Users/erikkerber/Dropbox/Projects/MillMain/MyLib.framework/BuddySDK(Pods-dummy.o) /Users/erikkerber/Library/Developer/Xcode/DerivedData/MillMain-fngfqhlslygksgcfuciznkpqfrbr/Build/Products/Debug-iphonesimulator/libPods.a(Pods-dummy.o) duplicate symbol _OBJC_CLASS_$_PodsDummy_Pods in: /Users/erikkerber/Dropbox/Projects/MillMain/MyLib.framework/BuddySDK(Pods-dummy.o) /Users/erikkerber/Library/Developer/Xcode/DerivedData/MillMain-fngfqhlslygksgcfuciznkpqfrbr/Build/Products/Debug-iphonesimulator/libPods.a(Pods-dummy.o) ld: 2 duplicate symbols for architecture i386 

我想如果他们要添加一个AFNetworking依赖关系,他们也会得到与AFNetworking相关的重复符号。

我打算最终分发MyLib与Cocoapods,但我也希望能够分发一个MyLib.framework本身。

有没有办法使Cocoapods与我的图书馆,同时使Cocoapods安全的任何潜在的用户?

简而言之,分发预构build库的唯一好方法是包括任何依赖关系,而是将其留给用户。 即在你的例子中,你会指示你的用户如何也将AFNetworking添加到他们的项目。 关于dummy文件基本上是一样的。

话虽如此,你当然可以去多种预build的变种:

  • 包含所有依赖关系。
  • 只包含你的lib的源代码,把依赖关系留给用户。

我们一直在谈论创build一个插件来生成独立的静态库,目的是你想要的,但是这还没有开始,可能需要一些时间。 (直到有人/有时间)

作为一种解决方法,您可以使用您的Podfile的post_install挂钩完全删除虚拟文件。 (这些只是像Testflight这样的非源代码库所需要的。)例如,如下所示:

 post_install do |installer| installer.project.targets.each do |target| source_files = target.source_build_phase.files dummy = source_files.find do |file| # TODO Fix this to the actual filename # puts "File: #{file.file_ref.name}" file.file_ref.name == 'TheDummyFile.m' end puts "Deleting source file #{dummy.inspect} from target #{target.inspect}." source_files.delete(dummy) end end 

这是未经testing的代码。

post_install钩子产生CocoaPods安装程序对象,从中你可以得到Pods.xcodeproj目标,你可以在这里find文档。 从那里,你可以深入研究并做任何你喜欢的项目,在运行这个钩子后保存到磁盘。

我遇到过同样的问题。 我使用以下podfile格式pipe理我的库与cocoapods的依赖关系:

 platform :ios, '6.0' pod 'AFNetworking' 

这导致了我的.a文件中的Pods-dummy.o文件。 如果我将这个库包含在另一个使用相同podfile格式的项目中,他们都创build了一个Pods-dummy.o符号,并导致链接器错误。 解决scheme是使用不同的podfile格式,这将导致名称空间的Pods-dummy符号:

 platform :ios, '6.0' target "MyProject" do pod 'AFNetworking' end 

这将导致Pods-MyProject-dummy.o文件,这将不会导致重复的符号。

注意:如果您将项目切换为使用新的podfile格式,请确保从项目中取消链接libPods.a,因为它将作为中断的链接挂起,因为新的pod库名为Pods-MyProject

如果他们是相同的,你可以合并他们使用:

 libtool (libtool -o merged.a file1.a file2.a) 

如果这不能解决这个错误,有这个选项: http : //atnan.com/blog/2012/01/12/avoiding-duplicate-symbol-errors-during-linking-by-removing-classes-from-静态库

参考http://guides.cocoapods.org/syntax/podfile.html#post_install&http://pdx.esri.com/blog/2013/12/13/namespacing-dependencies/

我使用“手动重命名所有符号”的方法。 我遇到了重复的符号_OBJC_METACLASS _ $ _ PodsDummy_Pods,所以我添加并编辑了Podfile中的post_install到类似的东西,以避免重复的符号

 post_install do |installer_representation| installer_representation.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited), PodsDummy_Pods=SomeOtherNamePodsDummy_Pods' end end end 

这个问题对我来说,当我手动添加一些外部代码到我的项目AFNetworking,例如,然后添加一些豆荚,也包括它。

从我自己的项目(而不是吊舱)简单地删除AFNetworking消除了这个问题。

将每个冲突符号的条目添加到其他C标志,例如“-DAFHTTPClient = AF2HTTPClient” Xcode多个静态库和重复符号