xcode 使用 cocoapods 构建静态库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17092822/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 03:29:46  来源:igfitidea点击:

Building a static library with cocoapods

iosxcodestatic-librariescocoapods

提问by javierdfm

I am trying to build a static library that has different dependencies (AFNetworking for example) specified in a Podfile. 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.

我正在尝试构建一个静态库,该库具有在 Podfile 中指定的不同依赖项(例如 AFNetworking)。我不希望将依赖项包含在最终的静态库中(调用 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? It should work just like linking with other existing frameworks.

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

Thanks!

谢谢!

回答by javierdfm

I solved it by removing the libPods.a lib from the section "Link Binary With Libraries" in Build Phases.

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

回答by Craig Russell

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. 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.

添加它的原因是因为 pod install 命令正在寻找静态库目标作为其要链接的目标之一。这可能是因为它是列表中的第一个目标(如果您没有明确指定目标,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 部分来明确说明您的目标,并省略静态库 target

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. If you have other targets that you do want to link with (an iPhone app target for instance) that's a good choice. But if your only real target is your static library, you need a little workaround.

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

My successful strategy so far has been to create a static library target (yes, a separate one from your mainstatic library) and call it "Dummy". Specify this target in your Podfile's link_with section.

到目前为止,我的成功策略是创建一个静态库目标(是的,与您的静态库分开)并将其称为“Dummy”。在 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'

回答by big_m

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; if you use the default Pods target, it's just called "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.

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

I tried a variation of Craig's answermyself, and found that the link_withstatement is also responsible for hooking up the xcconfig generated by Cocoapods, which provides the compiler flags that control the header search path. 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.

我自己尝试了Craig's answer 的一个变体,发现该link_with语句还负责连接 Cocoapods 生成的 xcconfig,它提供了控制头搜索路径的编译器标志。当然,您可以手动添加 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_withstatement within the targetblock 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_withunnecessary.

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

If you have a unit test target, create two separate targets. (I currently defa 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在两个目标中都使用了一组常见的 pod,因为抽象目标目前不是一种选择,但它们可能有一天会成为一种选择。)它看起来像这样:

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 podelements in the root of the Podfile, so that Cocoapods won't generate a default target. That way, each product gets a unique "Pods-target-dummy.m", and there's no conflict when those object files are linked together.

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