Supporting multiple toolchain versions

The Usage docs have a section on Handling version-specific logic, but reading that and looking at SE-209, I have to admit, I'm sorta unsure what the path going forward is going to be to try to continue to support multiple toolchain versions with releases.

The // swift-tools-version block doesn't really seem like it helps because it would need to be for the lowest version one intends to support (Say 3). But then how do you use the V4 additions (or the changes in SE-209)? Do we use #if swift(>=4.2) & swift(>=4.0) checks in Package.swift to gate off the differences? There also is the Package@swift-4.swift support, but the docs imply that shouldn't be needed.

Can the docs maybe get some specific examples of how a package would support things through these changes?

In looking to enable 4.2 support for swift-protobuf, starting playing with this again.

Thanks to the // swift-tools-version: line, it seems like I have to add a Package@swift-4.2.swift file to get the newer SwiftPM to honor the enums for swiftLanguageVersions (or we'd break someone still on Swift 4).

However, even with the new file, swift package generate-xcodeproj --output scratch/ the generated project file seems to still have SWIFT_VERSION = 4.0 for all the targets.

Should this work? Does generate-xcodeproj just have a bug at the moment?

This now pushes us to having three Package.swift files, is there a better way to deal with this given what the // swift-tools-version: also triggers?

SWIFT_VERSION thing sounds like a bug. Do you mind filing one?

We don't really have a good way to support multiple tools version right now. We need some proposal work to make this easier.

Oops, forgot to mention – here's my branch for SWIFT_VERSION:

Yeah, thats a bug!

SR-7993 opened for the issue (points here also).

Re multiple toolchains, so is continuing to have a Package@swift-###.swift going to the the best path forward at the moment? Trying to use #if swift(>=##)...#else...#endif seems blocked by the // swift-tools-version: not to mention how large it can make the file when you need to arguments to the Package() call.

Thank you!

See my earlier post: Supporting multiple toolchain versions - #4 by Aciid

I haven't thought about the possible solutions but I hope we can come up with a decent solution to allow package authors to support multiple versions of the PackageDescription API.

The main thing I ran into trying to use #if swift(>=##) blocks was // swift-tools-version: appears to be strict. If it instead as a way to indicate the min version of the package manager needed, then it seems like the #if swift() conditionals would likely be more useful (it might make for some long code because of needing distinct
Package() usages for different arguments, but it would allow one file).

I don't think its easily possible to use #if swift in the manifest file because of how that feature works. The new compiler version directive might be more appropriate if we want to go that route. I think we should look into extending the version specific manifest feature to address this issue.

The new directive requires a pretty recent toolchain, so that rules it out for most library authors since we tend to try to support old toolchains To allow customers to update when they are ready (I.e. not when in the middle of their own releases, etc.)

Sure but whatever feature we build to make this easier will most likely only work for future version of SwiftPM.

Is there any plan to decouple SwiftPM from Swift so that SwiftPM can be independently updated? I don't see any reason to hold of SwiftPM updates until new Swift version released.