Carthage: Detect when pre-built binaries were built with an incompatible version of swift

Created on 18 Jun 2016  路  8Comments  路  Source: Carthage/Carthage

Idea 1: Try to link the pre-built framework to some Swift code and see if it blows up.

Idea 2: Create a .swift-version file in the .zip and check that it matches the version of the current swift compiler.

1 would be preferable since it doesn't require anything special in the .zip.

Either way, Carthage could build from source if the pre-built binary doesn't pass the test.

enhancement help wanted

Most helpful comment

For idea 1, checking the build products themselves could also work:

  1. The .bcsymbolmap contains output of swift -version in it:
$ grep -r swiftlang *.bcsymbolmap
B19A2BC5-0313-36B5-930E-5B8B139C330A.bcsymbolmap:Apple Swift version 2.2 (swiftlang-703.0.18.5 clang-703.0.31)
B53E1F9A-A663-3BB5-BDA0-26B74C9869D5.bcsymbolmap:Apple Swift version 2.2 (swiftlang-703.0.18.5 clang-703.0.31)
  1. The auto-generated *-Swift.h (optional, but enabled by default) also contains the Swift version which generated it as a comment:
$ grep swiftlang Contentful.framework/Headers/Contentful-Swift.h
// Generated by Apple Swift version 2.2 (swiftlang-703.0.18.5 clang-703.0.31)

All 8 comments

Could Idea 1 link correctly, but then fail somehow at runtime? I would vote for Idea 2.

In response to this comment on #1000 how do you see multiple built frameworks per release working?

There also been talk about local caching (#1222). But I'd also like to add a way to detect different versions for frameworks attached to GitHub Releases (#1354).

It seems to be that there would be multiple zips per release, one per Swift version. For Carthage to download the correct binary, we would need some naming convention; otherwise carthage archive would have to put the built frameworks for multiple Swift versions into a single zip.

Alternatively, you could mandate a release per Swift version, though we're now in a situation where Swift 2.3 and Swift 3 can be supported simultaneously.

Let's see if we can solve this first and then talk about how to support multiple releases. I think it'd be fine if you could only have a binary for a single release鈥攖hink of it as an incentive to upgrade to the latest version of swift. 鈽猴笍

For idea 1, checking the build products themselves could also work:

  1. The .bcsymbolmap contains output of swift -version in it:
$ grep -r swiftlang *.bcsymbolmap
B19A2BC5-0313-36B5-930E-5B8B139C330A.bcsymbolmap:Apple Swift version 2.2 (swiftlang-703.0.18.5 clang-703.0.31)
B53E1F9A-A663-3BB5-BDA0-26B74C9869D5.bcsymbolmap:Apple Swift version 2.2 (swiftlang-703.0.18.5 clang-703.0.31)
  1. The auto-generated *-Swift.h (optional, but enabled by default) also contains the Swift version which generated it as a comment:
$ grep swiftlang Contentful.framework/Headers/Contentful-Swift.h
// Generated by Apple Swift version 2.2 (swiftlang-703.0.18.5 clang-703.0.31)

I might take a stab at this, but couple of questions:

  1. Whats the best approach to determining the user's local version of swift? Parse swift --version? Should we make any attempt to respect a .swift-version if it exists?
  2. Should we assume that versions must strictly match to be compatible? That's safe but may need to be changed after ABI stability.
  3. In the case of a failure to determine compatibility, should we be optimistic and try to use the framework anyway, or pessimistic and build? Pessimistic is safer, but optimistic is more in line with the current behavior.

Parse swift --version?

Yes, although it should be run through xcrun I think. xcrun swift --version.

Should we assume that versions must strictly match to be compatible?

Yes. AIUI, that's the only level of compatible that's actually supported.

In the case of a failure to determine compatibility, should we be optimistic and try to use the framework anyway, or pessimistic and build? Pessimistic is safer, but optimistic is more in line with the current behavior

Pessimistic, I think. Since the failure to use a pre-compiled binary isn't a hard failure (i.e. it won't prevent anyone from building), it's better to be pessimistic.

Alright. I'll give this a go.

So I'm pretty much done with this. I used the second method suggested by @neonichu (thanks!). But I have one more question: What about Objective-C frameworks? This pessimistic approach will automatically force these to be built. Is there something I can look for to let me know that a Framework is Objective-C instead of Swift?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yonaskolb picture yonaskolb  路  3Comments

rogernolan picture rogernolan  路  3Comments

3lvis picture 3lvis  路  3Comments

faustperic picture faustperic  路  3Comments

willhains picture willhains  路  3Comments