Cocoapods: Please support static libraries for Swift

Created on 25 Jul 2017  ·  44Comments  ·  Source: CocoaPods/CocoaPods

The release notes for Xcode 9 beta 4 note that

The new build system supports static library targets which contain Swift code. Debugging applications which use Swift static libraries may require having a complete set of build artifacts (in their original location) available. (33297067)

Also a tweet from Daniel Dunbar of Apple's dev tools team notes that this also applies to the old build system.

To date CocoaPods has (by necessity) required use_frameworks! for Pods written in Swift. This is no longer necessary. Since using a lot of frameworks can slow down app launch times, it would be really nice to see a future version of CocoaPods build with static libraries for Swift Pods.

hard enhancement

Most helpful comment

This is the primary feature of 1.5.0 since now 1.4.0 shipped.

Being snarky won't accelerate feature development. If anyone wants to see this feature faster implemented then please attempt to spend the time to do so. You can find the first PR here https://github.com/CocoaPods/CocoaPods/pull/6966.

If you cannot wait then just switch to another system that supports it.

All 44 comments

https://github.com/CocoaPods/CocoaPods/pull/6811 and https://github.com/CocoaPods/Core/pull/386 add support for this and will hopefully land in CocoaPods 1.4.0

Thanks, I guess I didn't search hard enough before posting.

Closing as a dupe 👍

Are those PRs actually the same? Static framework != static library, unless we expect the PRs will be updated to support static libraries.

Ah yeah, good point, 👍

Most likely............do we want to do a check for the current xcode version used?

You mean check the project attribute's last upgrade check?

Yeah anyway to be able to check the current version since this is support in Xcode9b4 currently, would we want to disable this check for Xcode 8 today?

It appears that currently just deleting that check is not enough. It looks like the first issue here is on the Swift side of things we need to set the SWIFT_INCLUDE_PATHS to point to the "$PODS_CONFIGURATION_BUILD_DIR/Foo" directory, which contains the Foo.swiftmodule which is inferred when the binary is inside a .framework (see here)

The next problem I've noticed with our project is that, since we have the same pods for multiple platforms such as Foo-iOS and Foo-watchOS, the PRODUCT_MODULE_NAME, which in this case defines the Foo_iOS.swiftmodule directory mentioned above, needs to match with the import from other modules. So in this case instead of being set to $(PRODUCT_NAME:c99extidentifier), it needs to be explicitly set to Foo

The next problem in our project is when you have a Swift pod depending on an Objective-C pod, since no umbrella header and modulemap are generated by CP for the Objective-C pod, your swift code cannot import it. To work around this you must create a module.modulemap in the same directory as your libFoo.a and it must contain a path to an umbrella header (which the library may or may not provide for you)

Something others might find off-putting when going through this process (although I consider it a feature) is that with dynamic frameworks, because of the umbrella headers that are generated by CocoaPods, for iOS, anything depending on a framework from CocoaPods implicitly has UIKit imported globally. This means you could have a file in your project that imports one of your pods, without importing UIKit (or Foundation) and still use types from those frameworks. This means when converting to static libraries, since this is no longer particularly the case, code that is unintentionally missing those imports may not compile until you add them.

I consider the implicit UIKit import a CocoaPods bug (see closed #6816), since it makes CocoaPods code less portable. There should at least be an option to disable it.

However, with PR #6772, the static frameworks that wrap static libraries work just like dynamic frameworks, including the UIKit import.

No pressure here, but is there any ETA on the 1.4.0 version which is where this issue would land?
Ideally with iOS 11 launch?

@keith So the dani_static_swift branch on CocoaPods should theoretically build with Swift static libs now. If you could give it a try on the Lyft project and let me know where it breaks, that would be great. The handling of headers is pretty hacky right now, but I'll fix that up in time.

So #6811 brought support for static frameworks (in podspecs), and the PR #6966 adds support for static swift libraries.

I tried the latter approach in a fairly big iOS project, but failed to build the project correctly.
I then tried to build what I’d call “Static Swift Frameworks” (the nomenclature of this topic still confuses me), so basically I built the project with use_frameworks!, but I made a few modifications in CocoaPods code, so that the frameworks are actually built as static frameworks (by setting the build setting MACH_O_TYPE to staticlib and updating the generated build phases of the main target), and the project built successfully.

As this was rather easy to implement and solved a really big problem for us (we’ve recently hit a hard limit of dynamic frameworks), and it required zero modifications to our source-code, I’m curious if a PR implementing this feature would be accepted? My concern is that this would probably require a new setting similar to the use_frameworks! setting, and only works with Xcode 9.

Cool! It would be nice to give the Podfile user the control.

The challenge and the reason we decided to go with the podspec approach in #6811 is that dealing with the combinations of source and vendored (dynamic and static) frameworks in the general case is tricky and will need a lot of thought not to be a support nightmare. We were also worried about the implications of building arbitrary pods as static frameworks when they may not have ever been tested that way.

Perhaps, it could be feasible to implement a use_static_frameworks! option and require all frameworks to be source or vendored_frameworks with static libraries. Then you wouldn't need to worry about the implications of mixing in dynamic library frameworks.

Is this still being worked on?

If anyone wants to build their dynamic frameworks statically with Xcode9 and CocoaPods 1.3.1 and is feeling adventurous, please give my CocoaPods-plugin a try: https://github.com/b-ray/cocoapods-static-frameworks

Punted to 1.5.0.

Would it be possible for someone to summarise where things are with regards static linking of swift based pods? There seem to be several related issues around this and not clear (to me at least) exactly what is being proposed / worked on. Thanks !

@mwoollard TL;DR we roughly know what needs to be done to make this PR work, however I also need to take some time to clean up some of the pod integration code at the same time to make it easier to maintain going forwards.
It’s also a hard set of changes for me to test, as I don’t have a particularly broad set of test applications any more.
I’ve deproritised it for now, as it’s going to require some deeper thinking, and improving support for swift versions is more valuable in the short term.

So this feature is to be able to publish pod with swift source code as a static framework? What about integrating source swift pods statically? For the latter I have experimented with post_install script to effectively do this (by removing the dynamic linking and including the the object files created building the dynamic framework into the link phase - but would great if this was a feature. Have a reasonably complex setup ideally would like to be able to result in a single binary - can elaborate and happy to help / test as this moves forward. Mark

@mwoollard This feature (and open PR) is for integrating Swift libraries as source static libraries - Support for Swift Static Frameworks landed in 1.4.0.beta.1.

@mwoollard Some Swift-specific capabilities for static frameworks missed beta.1, but are in now in master branch. See a simple example in https://github.com/mukeshthawani/TestStaticFramework, along with corresponding issue #7117 and PR in #7135.

Let me know if you find anything missing.

any progress?

It's been 84 years...

This is the primary feature of 1.5.0 since now 1.4.0 shipped.

Being snarky won't accelerate feature development. If anyone wants to see this feature faster implemented then please attempt to spend the time to do so. You can find the first PR here https://github.com/CocoaPods/CocoaPods/pull/6966.

If you cannot wait then just switch to another system that supports it.

I meant no disrespect, I like using CP very much, it's just been a long time since last activity related to this. Looking forward to this update :)

This is the primary feature of 1.5.0 since now 1.4.0 shipped.

@dnkoutso Can you clarify in your blog that it WASN'T actually released with 1.4.0?
http://blog.cocoapods.org/CocoaPods-1.4.0/

That's weird because after updating to 1.4.0 (from 1.3.1) my project build time has reduced from ~5min to ~40s 😵 Is that placebo?

Hey guys, as now cocoapod 1.5 beta is released so I am assuming I can have my project using both objective c libraries and as well as some swift libraries via pod, but I am not been able to find any example pod file for doing that. Can someone share a sample pod file to achieve this.

@msalman: simply remove use_frameworks! from the Podfile. https://stackoverflow.com/a/49347198/1033581

Is it possible to mark some of pods as dynamic frameworks?

I removed use_frameworks! but ran into a No such module. What is the cause of that?

@alper did you resolve your issue? If so, how did you do so?

@macbellingrath I just gave up for now and will try again some time in the near future.

@alper, @macbellingrath, for ObjC pods, you need to add :modular_headers => true. Example:

pod 'SSZipArchive', :modular_headers => true

It's explained in http://blog.cocoapods.org/CocoaPods-1.5.0/

Still breaks for me on SAMKeychain and FirebaseCore.

@Coeur No reported FirebaseCore integration issues at https://github.com/firebase/firebase-ios-sdk/issues. As far as I can tell the same is true on StackOverflow.

@Coeur Do you really consider it a Firebase issue when someone locks their Podfile to an old version and want to add a new component that requires a newer version of that dependency? There's nothing new about problems like that and it's an example of CocoaPods doing the right thing and catching a bad configuration as early as possible. If anything, CocoaPods should output more information about how to diagnose and fix the issue.

@paulb777 looking more closely, you're right about it. My apologies.

Was this page helpful?
0 / 5 - 0 ratings