[swift-build-dev] Hello SPM

Eloy Durán eloy.de.enige at gmail.com
Tue Dec 8 08:45:59 CST 2015

> Sorry, I wasn't clear here.
> What I meant was is the *implementation* of CocoaPods actually able to use Swift libraries. I'm wondering if it would ever be viable to factor out shared libraries that both projects used, but I can imagine that using (and installing) those libraries from the Ruby based CocoaPods might be non-trivial?

Ah, I see. It would involve some work, but I’m sure it’s something we can overcome, when the benefit of sharing said components outweighs the complexity of writing some CRuby/Swift bindings. Right now I’m not sure which components that would be –maybe the Xcode integration part in the future?–, but we’ll keep this possibility in mind as we go forward.

> I think both of those are things it makes sense to add soon (and encourage people to author).

Ace. I see you already commented on that Chocolat ticket, will answer there.

> One evolutionary approach I have considered is that we could, for C-family projects, provide built in tools to define adaptor packages which integrate non-conforming projects into the system. This is analogous to how we support module-map packages today, even though in an ideal world projects would ship module definitions with their project. This would allow the ecosystem to build up, and people would begin to see the value of it. At that point, the owners of the adaptor packages could upstream their work into the project itself. And then we would all live in a better world! :)

Oooh, this sounds good. I’d love to hear more about this when.if you have more details. It sounds like this might be an interesting place where we can provide an adapter that would make libraries covered by CP only to be usable by SPM while they are not natively supported yet, or ever.

> One of the specific things I was curious about was how CocoaPods has historically handled changes to the podspec definition format?

- A lot of build options would initially be set through a simple `xcconfig` dictionary and a `compiler_flags` list.

- A big reason for me to choose Ruby for CP was that, because of Ruby’s nature:
  * lib authors could amend the way a library was integrated with a Ruby post-install hook in their lib’s podspec that had complete access to the library integration code
  * users could basically monkey-patch the complete system from their Podfile (the root spec, shall we say)
  This was an often recommended (we’d give them code suggestions of how/what to patch) and ask them (both lib authors and end-users) to report back to us with the solutions they came up with.

In both cases we’d use the data that we received, about what people actually needed, to decide what the podspec definition should look like. Because of this there haven’t been many podspec additions that we felt we needed to revert.

Obviously this complete freedom comes at a price and now that we pretty much have everything in the format that we need we’ve started locking that down. Using the `xcconfig` dictionary is discouraged and the post-install hooks have been replaced from the podspec format for a shell command: https://guides.cocoapods.org/syntax/podspec.html#prepare_command

(post-install hooks are still a supported and valuable thing in the Podfile format, though. The end-user should be able to do whatever they need.)

> How does this work if a podspec and its dependencies start requiring incompatible versions of CocoaPods itself?

A ‘spec repo’ may contain a file that indicates what the minimal CP version that is required to work with the specs in that spec repo. The CLI tool simply stops working and informs the user to upgrade if their version is older than the minimal required version for that spec repo.

For example, the minimal required version for the public central spec repo is 0.32.1 (over a year old): https://github.com/CocoaPods/Specs/blob/master/CocoaPods-version.yml.

But as we use a simple DB for our index (FS, probably in a SCM repo) users that really can’t upgrade their CP version yet, or don’t want to yet because of other time constraints, can easily use an older tree / branch. (This is something that people, specifically larger companies, have definitely done in the past.) Because of this flexibility, we were free to make breaking changes when we really deemed them necessary.

> Have you just managed  to avoid this, or are there legacy features you have ended up supporting but wish you didn't need to? I see things like issue #840 which I assume reflects some of how this worked out in practice.

* The Podfile format is indeed something that in hindsight is very clear should have been the way as described in #840 from the get-go, but it’s also going to be pretty much the only real big breaking change we’ll be making, so I don’t see it as a big problem. People have still been able to build their complex multi-platform projects, this API change would be a one time major clean-up of everything we now know people require.

* Static libraries with resources were a major pain, because the way the lib code often referenced them (through the NSBundle API) meant that all the resources would have to go into the main app bundle, which could easily lead to duplicate filenames. We ended up adding functionality to create ‘resource bundles’ and over time lib authors started using this pattern more and more, but the complexity we needed to deal with for this is something I really wish we didn’t needed to deal with. https://guides.cocoapods.org/syntax/podspec.html#resource_bundles. We had hoped that dynamic frameworks becoming available on iOS would finally solve all such woes, but alas those tend to load way too slow (https://github.com/artsy/eigen/issues/586). Have you given any thought yet to how you’d like to deal with resources and embedding those in a bundle?

* Subspecs are something that I really don’t like and wish we didn’t need to support. https://guides.cocoapods.org/syntax/podspec.html#subspec. It was pretty much only added to support the monolithic libraries that were being build, especially from the pre-iOS era. I don’t like having source that I don’t use in my app, which includes dependencies of such code. So the only reason we saw to deal with that was to allow a CP user to specify what subsets of the monolithic library they wanted to use.

  Subspecs make some implementation more complex than we’d like and I personally prefer the approach of micro libs and a spec for each, *but* I should add that many in the community actually really like using subspecs.

* Another thing that I remember that I was very glad we got rid of was determining platform specific settings at spec evaluation time, which made specifications very hard to use in environments where users were targeting multiple platforms, let alone once more platforms were being introduced. i.e. you used to be able to do something like:

    common_files = ‘Common/..'
    if config.osx?
      spec.source_files = common_files + ‘OSX/…'
      spec.source_files = common_files + ‘iOS/…’

  Nowadays you specify them all and their platform scope:

    spec.source_files = ‘Common/…’
    spec.osx.source_files = ‘OSX/...’
    spec.ios.source_files = ‘iOS/...'

– Eloy
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-build-dev/attachments/20151208/598e3749/attachment.html>

More information about the swift-build-dev mailing list