【问题标题】:Configuring Cocoapods with an existing static library and iOS application使用现有的静态库和 iOS 应用程序配置 Cocoapods
【发布时间】:2013-05-08 23:01:48
【问题描述】:

我无法让我的工作区使用 Cocoapods 正确编译。工作区中有 3 个项目,每个项目都有自己的目标:

  1. libPods - 具有所有外部依赖项的 Cocoapods 静态库
  2. libCommon - 我的静态库,用于保存所有共享代码(基本控制器、网络代码、通用 UI 等)
  3. myApp - 我的 iOS 应用程序

libCommon 和 myApp 都需要来自 libPods 的外部依赖项。最初我认为它会像这样工作:

  1. libPods 构建
  2. 针对 libPods 和构建的 libCommon 链接
  3. myApp 与 libCommon 和构建链接

在这种情况下,libCommon “拥有” pod,然后 myApp 只是链接到 libCommon,就像我一直在做 pre-Cocoapods 一样......但显然静态库不喜欢与静态库链接(我得到了一堆动态库错误)。我在某个地方读到了一个 github 问题,我应该构建 libPods 和 libCommon,然后 myApp 应该链接到这两个库。现在我的 podfile 看起来像这样:

workspace 'MyApp.xcworkspace'
platform :ios, '5.0'

link_with ['Common', 'MyApp']

target 'MyApp' do
  xcodeproj 'MyApp.xcodeproj'

  pod 'AFNetworking',               '1.1.0'
  pod 'TTTAttributedLabel',         '1.6.0'
  pod 'JSONKit',                    '1.5pre'
  pod 'Reachability',               '3.1.0'
end

通过此设置,myApp 拥有所有 pod,然后在 libCommon 构建设置中,我指定了 pod 标头的路径。在我尝试使用 libCommon 中的一个类之前,这构建正常。一旦我这样做了,我就会得到其中一个_OBJC_CLASS_$_Blah 错误(它告诉我虽然标题可用,但它仍然没有正确链接)。当我尝试在“构建阶段”中手动链接 libCommon 时,我得到一堆重复的符号错误(这让我相信它已经链接了?)。什么鬼?

正确执行此操作的方法是什么?我的 podfile 应该是什么样的?

【问题讨论】:

    标签: ios xcode static-libraries cocoapods


    【解决方案1】:

    CocoaPods 创建一个隐式根目标,默认情况下它与项目的第一个目标链接。当您正在创建另一个目标并且链接_with 选项不被子目标定义继承时,您的设置不起作用。为了制作 link_with 选项,您可以将其移动到 MyApp 目标定义的块内。

    由于 Common 目标与 Pod 链接,如果您将它们与 MyApp 链接,则会导致应用程序与 Common 链接时出现重复符号错误。在这种情况下,您只需使标头可用于 MyApp 目标。这很简单,但还没有合适的 DSL,所以目前作为解决方案有点 hacky(但受支持)。

    workspace 'MyApp.xcworkspace'
    platform :ios, '5.0'
    
    target 'Common' do
      pod 'AFNetworking',               '1.1.0'
      pod 'TTTAttributedLabel',         '1.6.0'
      pod 'JSONKit',                    '1.5pre'
      pod 'Reachability',               '3.1.0'
    
      target 'MyApp', :exclusive => true do
        xcodeproj 'MyApp.xcodeproj'
      end
    end
    

    【讨论】:

    • 我不知道你怎么这么快就回答 cocoapods,法比奥,但请注意,非常感谢!我以前也遇到过类似的问题,'exclusive' 选项解决了它。
    • 我已经按照您的建议进行了设置,并且 MyApp 目标编译成功,直到我尝试使用 Common 中的类(例如:添加此行:MyObject *objectFromCommon = [[MyObject alloc] init ]; 导致 _OBJC_CLASS_$_MyObject 错误)。解析器/语法突出显示很好,这让我相信标头可用,但 lib 仍然没有链接。想法?
    • @user2393462435,您需要在框架构建阶段手动链接Common 目标和MyApp 目标(CocoaPods 不管理您的目标)。
    • @Fabio,当我手动链接时,它会导致重复的符号错误。呃,可能不得不放弃cocoapods。我很惊讶我的项目设置并不常见..
    • 这在大多数情况下都有效。但是,它没有做的是链接 MyApp 中 Common 的所有依赖项。所以它最终不起作用。我发现如果我在根目录中添加了一个带有“MyApp”的链接,然后在安装后我在构建阶段从 MyApp 中删除了 libPod.a(停止重复符号)它会起作用。但是谁想要所有这些额外的工作呢?
    【解决方案2】:

    针对这种情况我采用的解决方案如下:

    我很简单地设置了 Podfile:

    workspace 'MyApp.xcworkspace'
    platform :ios, '5.0'
    
    xcodeproj 'Common.xcodeproj'
    
    pod 'AFNetworking',               '1.1.0'
    pod 'TTTAttributedLabel',         '1.6.0'
    pod 'JSONKit',                    '1.5pre'
    pod 'Reachability',               '3.1.0'
    
    target 'MyApp' do
        xcodeproj 'MyApp.xcodeproj'
        # specific dependencies
    end
    

    通过这种方式正确设置了 Common lib 和 MyApp 以使用所有依赖项。但是,这仍然会导致重复符号。解决这个问题的方法是简单地从 Common 项目的 Build Phase 中删除 libPods.a。这很好,因为我们真的不想将 Cocoapods 静态库链接到我们的静态库。当您构建应用程序时,所有正确的依赖项都将被链接,并且所有正确的头文件路径都在 .xccconfig 文件中设置,因此 Xcode/AppCode 仍将提供您所有的自动完成功能,并且一切都会编译。

    您需要在每次运行 pod install 时删除 libPods.a,这有点麻烦,但与手动管理所有依赖项相比,这样做可能会更好。

    更新:我正在写这篇文章,我刚刚注意到不要使用在静态库中设置的链接器标志 Cocoapods 很重要。默认情况下,我的静态库已经用没有值覆盖了它们的值,但 Cocoapods 对此发出警告并建议您使用 $(inherited)。无视就好。

    【讨论】:

    • 您知道自动删除的方法吗?我想添加它,以便我的构建服务器可以在每次构建之前执行“pod install”。
    • 如果您在同一个文件夹中有三个项目,您如何解决这个问题。 “MyApp-Core”、“MyApp-iOS”和“MyApp-Mac”?
    • 我遇到的问题是 Podfile.lock 或 Manifest.lock 显示“没有此类文件或目录”。另外,“沙盒与 Podfile.lock 不同步”
    猜你喜欢
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 2015-07-18
    • 2013-06-10
    • 1970-01-01
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    相关资源
    最近更新 更多