Cocoapods: use_frameworks! for only some pods

Created on 19 Jul 2015  Â·  29Comments  Â·  Source: CocoaPods/CocoaPods

This is a feature request, to allow use_frameworks! to apply to only some pods. It is often desirable to let the linker strip unused code during static linking, and switching everything to dynamic frameworks would prevent that.

Obviously some pods with Swift or resources or whatnot can't be static, but many can. (Should this be in the spec, perhaps?)

discussion

Most helpful comment

@mommyme The solution is to stop using CocoaPods. Use Carthage, where you are responsible how you integrate your dependencies, some may be dynamic, some static.

All 29 comments

I don't think this is something we really want to support, especially as the linker can't really strip very much ObjC

In practice, my app is 30% larger when using use_frameworks!. There is only one pod which I would like to be a framework (and only for Storyboard IBDesignable reasons, so it seems silly to impact app size).

This won't be possible for the general case, because of transitive dependencies. If Pod A is build dynamically and depends on Pod B that is build statically and the app also depends on Pod B, it is for example impossible to build, because either Pod A will be missing the symbols of Pod B at link time, or you end up with multiple copies of Pod B. There are probably more scenarios which won't work.

However, you should be able to create a plugin to support specific cases like yours.

In your example, I would expect multiple copies of B. That's not so bad. If it's crucial that it be shared (global state or somesuch), maybe Pod B's spec could indicate that, and promote to a framework in the case of transitive dependencies.

@ghazel duplicating B will cause duplicate symbols, which leads to _massive_ headaches

Will it? The app and the framework each have a separate copy of the symbol, so each should get their own.

There's only one runtime, though, so class identity will break and there will be the familiar linker warning telling you about undefined behaviour being involved.

Generally, I don't think this is something we can realistically support in a way that doesn't break most of the time. That's why I rather suggest to do a plugin to limit it to very specific cases.

But then when the framework gets dynamically linked to the app, which symbol gets used is undetermined -- and my guess is that duplication would cause even greater binary bloat than just using dynamic frameworks in the first place

Hm. Well, always hoisting to framework in the case of a shared dependency is not such a bad answer.

Always hoisting doesn't necessarily work either. If a Pod's code is compiled with (or its vendored_libraries were compiled with) symbol visibility hidden by default, but the author didn't set visibility attributes properly, then the hoisted framework won't export those symbols and they will not be discoverable from the other targets that need them.

This is more likely to be a problem with vendored_libraries pods, and it doesn't seem that there's a quick way to tell other than "link and run nm -g". And, of course, it might not be the only problem with hoisting to a framework.

Well, if a pod can't be hoisted to a framework, than the existing use_frameworks! won't work either.

Right, that's true. use_frameworks! fails in this case. Compiling static libraries into dynamic frameworks is tricky voodoo, and can cause linker failures that are very puzzling.

I think the idea is to front-load the error and make it obvious, rather than have things fail opaquely during the build. There's no obvious indication that's yet been discovered in a static library that indicates whether or not it can properly be linked into a dynamic framework. If there were a quick and reliable way to determine that, then perhaps the check could be enhanced to run that test and only fail if a library fails that test.

Perhaps the pod spec could declare how it can be used. Not the most automated, but the most controllable.

It sounds like this sort of mixed approach does need to be supported, though, since there are some pods which must be frameworks, and some which must not be.

@segiddins Unfortunately there are some pods that are mere delivery mechanisms for static libraries. The Google adwords tracker is one. So is PSPDFKit (though in that case it's a framework and resource bundle). use_frameworks breaks them entirely.

Would it be fair to allow pods without any compiled sources to use the old non-framework behavior?

Without a workaround this forces us to bifurcate dependency management.

@russbishop Pods which truly are only a static library will be linked against the user target directly. There's currently an issue with the setup of header search paths for them when using use_frameworks! (see #3859), but once that's fixed they work.

I'm unclear on the current status of this issue. I understand that importing the same static libraries across multiple frameworks may not be supportable due to duplicate symbols, but it seems this shouldn't block support for incorporating static pods directly in the app, or for having pods built as static libraries reference pods built as frameworks. If I understand @neonichu's comment correctly, static pods will currently work only if they just vend a static library. It would seem this could be supported more generally with the limitation that pods built or vended as static libraries not be used by pods built as frameworks.

Currently, we have a private pod which references other pods that do not yet support being built as frameworks, but want to add functionality from a Swift (framework) pod. Is this a case that can be supported? Due to the existing dependencies, the private pod must be built as static.

This is, at the end of the day, a scenario that CocoaPods won't support.

@ghazel How did you go about solving this problem?

I just avoided using use_frameworks! at all.

Me too. Sad that it has to come to that.

On Jun 29, 2016, at 9:57 PM, Greg Hazel [email protected] wrote:

I just avoided using use_frameworks! at all.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.

@segiddins what do you recommend for someone who has some pods that are written in swift and others for which use_frameworks! causes great problems? Is there a workaround you recommend?

@mommyme there's no silver bullet for situations like that (other than the not-helpful answer of "get things working as frameworks" which isn't always even possible), sorry :(

I wish I could Samuel. Some large ones are out of my control : ( Thanks for taking the time to answer though. If you hear of any workarounds, please let me know.

On Jul 10, 2016, at 9:50 AM, Samuel Giddins [email protected] wrote:

@mommyme there's no silver bullet for situations like that (other than the not-helpful answer of "get things working as frameworks" which isn't always even possible), sorry :(

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@mommyme try using packager plugin

I meet this problem,too!

@mommyme The solution is to stop using CocoaPods. Use Carthage, where you are responsible how you integrate your dependencies, some may be dynamic, some static.

Or wait for #6899

Is this feature still void after over 2 years?

@muxi given no one on the CocoaPods team will have time to build this feature for the foreseeable future and no one else has tried to contribute it, there's no further update to give

Was this page helpful?
0 / 5 - 0 ratings