【问题标题】:Building a static library with cocoapods使用 cocoapods 构建静态库
【发布时间】:2013-06-10 04:16:40
【问题描述】:

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

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

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

谢谢!

【问题讨论】:

  • 如果您在下面添加的答案是正确的,请将其标记为正确,这样该问题就不再显示为未决。

标签: ios xcode static-libraries cocoapods


【解决方案1】:

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

【讨论】:

  • 我相信这是正确的答案,我在这里详细说明我的解决方案:stackoverflow.com/a/17869668/106703
  • 有什么聪明的方法可以自动删除吗?我尝试了多种方法都没有成功。
  • @Wilmar,请参阅我的自动删除答案(或者更具体地说,如何避免首先添加它)。
【解决方案2】:

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

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

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

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

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

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

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

platform :ios, '5.1.1'

link_with ['Dummy']

pod 'AFNetworking', '= 1.3.1'

【讨论】:

  • 这很好用,但你可能还需要将静态库目标的配置设置为Pods.xcconfig,否则依赖库的头文件无法在你的静态库中使用。
  • 您可能需要手动将 Cocoapods 生成的 xcconfig(例如,Pods.debug.xcconfig)添加到 Xcode 项目的配置(项目 > 信息 > 配置)中,以便标题搜索工作。我确实让这种模式起作用,但我想出了another solution
【解决方案3】:

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

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

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

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

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

如果静态库目标的名称(在您的 Xcode 项目中)不同,您可以在 target 块中包含 link_with 语句,但如果只有一个目标,我通常更喜欢在这两个地方都不需要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”,并且当这些目标文件链接在一起时不会发生冲突。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-10
  • 2018-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多