简体   繁体   中英

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

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.

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.

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.

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.

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 .

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.

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.

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". Specify this target in your Podfile's link_with section.

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.

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.

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

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.

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 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. That way, each product gets a unique "Pods- target -dummy.m", and there's no conflict when those object files are linked together.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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