17

我正在尝试构建一个在 Podfile 中指定的具有不同依赖项(例如 AFNetworking)的静态库。我不希望依赖项包含在最终的静态库中(调用 libMyProject.a),我只想链接它们,然后创建一个 MyProject.Podspec 文件,我可以在其中放置相同的依赖项。

问题是,当我构建 libMyProject.a 时,libPods.a 被链接并包含在内,因此如果我分发 libMyProject.a 并且其他人将它集成到使用某些相同依赖项的项目中,则会出现重复符号问题。

如何链接 libPods.a 库但不将其包含在 libMyProject.a 中?它应该像链接其他现有框架一样工作。

谢谢!

4

3 回答 3

12

我通过从 Build Phases 中的“Link Binary With Libraries”部分中删除 libPods.a lib 解决了这个问题。

于 2013-06-17T08:21:34.783 回答
6

虽然从“Link Binary with Libraries”构建阶段手动删除 libPods.a 确实有效,但真正的答案是首先不要让它被添加到那里。

添加它的原因是 pod install 命令将静态库目标作为要链接的目标之一。这可能是因为它是列表中的第一个目标(如果您没有明确指定目标,cocoapods 的实现会导致它选择第一个目标)或者可能是因为您在“link_with”部分中明确说明了它。

我找到的答案是使用 Podfile 的 link_with 部分来明确说明您的目标,并省略静态库 target

pods 项目仍在创建中,并且您的依赖项如您所料那样被带入其中,但 libPods.a 并未添加到静态库的构建阶段。

唯一的问题是在 link_with 部分中放入什么,如果不是你的静态库的话。如果您确实想要链接其他目标(例如 iPhone 应用程序目标),这是一个不错的选择。但是,如果您唯一真正的目标是静态库,则需要一些解决方法。

到目前为止,我成功的策略是创建一个静态库目标(是的,与您的静态库分开)并将其称为“虚拟”。在 Podfile 的 link_with 部分中指定此目标。

这有点令人反感,当然,但它确实有效。

platform :ios, '5.1.1'

link_with ['Dummy']

pod 'AFNetworking', '= 1.3.1'
于 2014-02-06T16:47:54.087 回答
1

引用的库(默认情况下)不包含在静态库产品中。您看到的链接器冲突更有可能是您的静态库和客户端应用程序都使用默认(隐式)Pod 目标的结果。

每个 Cocoapods 生成的目标都包含一个编译到产品中的“Pods-target-dummy.m”文件如果你使用默认的 Pods 目标,它就叫做“Pods-dummy.m”。当库和客户端都使用默认目标时,编译虚拟文件产生的相同符号将导致链接错误。

我自己尝试了Craig 答案的变体,发现该link_with语句还负责连接 Cocoapods 生成的 xcconfig,它提供了控制标头搜索路径的编译器标志。当然,您可以手动添加 xcconfig(或标题搜索路径项目设置),但我一直在为我的团队寻找可重复的解决方案。

我的解决方案是为库创建一个显式目标,其名称不太可能与客户端项目发生冲突(例如,库的名称):

target 'XYZLibrary' do
    pod 'AFNetworking', '2.5.2'
    ...
end

如果静态库目标的名称(在您的 Xcode 项目中)不同,您可以在块中包含一条link_with语句target,但如果只有一个目标,我通常更喜欢在两个地方使用相同的名称,这样就link_with没有必要了。

如果您有一个单元测试目标,请创建两个单独的目标。(我目前def有一组用于两个目标的通用 pod,因为抽象目标目前不是一个选项,但它们可能有一天会出现。)它看起来像这样:

def common_pods
  pod 'AFNetworking', '2.5.2'
end

target 'XYZLibrary' do
  common_pods
end

target 'XYZLibraryTests' do
  common_pods
end

关键是 Podfile 的根目录中不要有任何pod元素,这样 Cocoapods 就不会生成默认目标。这样,每个产品都会获得一个唯一的“Pods- target -dummy.m”,并且当这些目标文件链接在一起时不会发生冲突。

于 2015-05-05T15:48:32.867 回答