简体   繁体   English

使用cocoapods构建静态库

[英]Building a static library with cocoapods

I am trying to build a static library that has different dependencies (AFNetworking for example) specified in a Podfile. 我正在尝试构建一个静态库,它具有在Podfile中指定的不同依赖项(例如AFNetworking)。 I don't want the dependencies to be included in the final static library (call libMyProject.a), I just want to link against them and then create a MyProject.Podspec file where I can put the same dependencies. 我不希望依赖项包含在最终的静态库中(调用libMyProject.a),我只想链接它们,然后创建一个MyProject.Podspec文件,我可以在其中放置相同的依赖项。

The problem is that when I build libMyProject.a the libPods.a is linked and included, so that if I distribute libMyProject.a and other people integrates it in a project which uses some of the same dependencies it will have duplicate symbols issues. 问题是,当我构建libMyProject.a时,libPods.a被链接并包含在内,因此如果我分发libMyProject.a而其他人将它集成在一个使用某些相同依赖项的项目中,则会出现重复的符号问题。

How can I link against the libPods.a lib but not include it in libMyProject.a? 如何链接libPods.a lib但不包含在libMyProject.a中? It should work just like linking with other existing frameworks. 它应该像链接其他现有框架一样工作。

Thanks! 谢谢!

我通过从Build Phases中的“Link Binary With Libraries”部分删除libPods.a lib来解决它。

Whilst manually removing the libPods.a from the "Link Binary with Libraries" build phase does indeed work, the real answer is to not let it get added there in the first place. 虽然从“Link Binary with Libraries”构建阶段手动删除libPods.a确实有效,但真正的答案是不要让它首先添加到那里。

The reason it is added is because the pod install command is finding the static library target as one of its targets to link with. 添加它的原因是pod install命令正在查找静态库目标作为其链接目标之一。 This could be because it is the first target in the list (cocoapods' implementation causes it to pick the first one if you haven't explicitly specified targets) or it could be because you have explicitly stated it in the 'link_with' section. 这可能是因为它是列表中的第一个目标(如果你没有明确指定目标,cocoapods的实现会导致它选择第一个目标),或者可能是因为你已经在'link_with'部分中明确说明了它。

The answer I find is to use the link_with section of the Podfile to explicitly state your targets, and omit the static library target . 我找到的答案是使用Podfile的link_with部分显式声明目标,并省略静态库目标

The pods project is still created, and your dependencies brought into there as you'd expect, but the libPods.a isn't added to the build phase of your static library. pods项目仍然是创建的,您的依赖项会按照您的预期进入,但libPods.a不会添加到静态库的构建阶段。

The only problem is what to put into the link_with section, if not your static library. 唯一的问题是如何放入link_with部分,如果不是你的静态库。 If you have other targets that you do want to link with (an iPhone app target for instance) that's a good choice. 如果您有其他想要链接的目标(例如iPhone应用程序目标),那么这是一个不错的选择。 But if your only real target is your static library, you need a little workaround. 但如果您唯一真正的目标是静态库,则需要一些解决方法。

My successful strategy so far has been to create a static library target (yes, a separate one from your main static library) and call it "Dummy". 到目前为止,我的成功策略是创建一个静态库目标(是的,与静态库中的一个单独的目标)并称之为“Dummy”。 Specify this target in your Podfile's link_with section. 在Podfile的link_with部分中指定此目标。

It is a little distasteful, granted, but it does work. 这有点令人反感,但它确实有效。

platform :ios, '5.1.1'

link_with ['Dummy']

pod 'AFNetworking', '= 1.3.1'

Referenced libraries are not (by default) included in the static library product. 默认情况下,引用的库不包含在静态库产品中。 The linker conflict you're seeing is more likely the result of both your static library and the client app both using the default (implicit) Pod target. 您看到的链接器冲突更可能是静态库和客户端应用程序都使用默认(隐式)Pod目标的结果。

Every Cocoapods-generated target includes a "Pods- target -dummy.m" file that is compiled into the product; 每个Cocoapods生成的目标都包含一个编译到产品中的“Pods- target -dummy.m”文件; if you use the default Pods target, it's just called "Pods-dummy.m". 如果你使用默认的Pods目标,它就叫做“Pods-dummy.m”。 When both the library and client use the default target, the identical symbols produced from compiling the dummy files will cause a link error. 当库和客户端都使用默认目标时,编译虚拟文件产生的相同符号将导致链接错误。

I tried a variation of Craig's answer myself, and found that the link_with statement is also responsible for hooking up the xcconfig generated by Cocoapods, which provides the compiler flags that control the header search path. 我自己尝试了Craig的一个变种,发现link_with语句还负责连接Cocoapods生成的xcconfig,后者提供控制头搜索路径的编译器标志。 You can add the xcconfig (or the header search path project settings) manually, of course, but I went looking for a repeatable solution for my team. 当然,您可以手动添加xcconfig(或标题搜索路径项目设置),但我为我的团队寻找可重复的解决方案。

My solution is to create an explicit target for the library, with a name that is unlikely to cause conflicts with a client project (for example, the name of the library): 我的解决方案是为库创建一个显式目标,其名称不太可能导致与客户端项目冲突(例如,库的名称):

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

You can include a link_with statement within the target block if the name of the static library target (in your Xcode project) is different, but if there's only one target, I usually prefer to use the same name in both places, making link_with unnecessary. 如果静态库目标的名称(在Xcode项目中)不同,则可以在target块中包含link_with语句,但如果只有一个目标,我通常更喜欢在两个地方使用相同的名称,从而无需使用link_with

If you have a unit test target, create two separate targets. 如果您有单元测试目标,请创建两个单独的目标。 (I currently def a set of common pods that are used in both targets, since abstract targets are not currently an option, but they may be one day.) It looks like this: (我目前def一组在两个目标中常用的豆荚,因为抽象的目标不是目前的选择,但他们可能是一天。)它看起来像这样:

def common_pods
  pod 'AFNetworking', '2.5.2'
end

target 'XYZLibrary' do
  common_pods
end

target 'XYZLibraryTests' do
  common_pods
end

The key is to not have any pod elements in the root of the Podfile, so that Cocoapods won't generate a default target. 关键是Podfile的根目录中没有任何pod元素,因此Cocoapods不会生成默认目标。 That way, each product gets a unique "Pods- target -dummy.m", and there's no conflict when those object files are linked together. 这样,每个产品都会获得一个独特的“Pods- target -dummy.m”,当这些目标文件链接在一起时就没有冲突。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM