[Pitch] SPM: Lift ‘minimum deployment target’ constraint for package dependencies

Swift Package manager currently constrains the inclusion of a dependency to packages with an equal or lower deployment target than the host package. While this is intuitive at first-glance, in practice, the limitation causes issues and workarounds that are undesirable.

Elsewhere in the system, it is permitted to import libraries that aren't available to the minimum deployment target. You just need to gate usage of that library's APIs behind availability checks:

// App with <iOS 13 deployment target.
import SwiftUI // introduced iOS 13. No worries, you can import here.
...

@availability(iOS 13, *)
var someCoolView: some View { // This is fine.
    ...
}

However, with SPM, if you wish use a package behind availability checks, you can't – as you can't include the library as a dependency in the first place. Developers have been getting around this restriction by branching packages, lowering the minimum deployment target and marking all APIs with @available attributes. Package maintainers have been working around this issue by doing the same thing.

It would be far more convenient if Swift Package Manager allowed dependencies with greater minimum deployment targets than the target application's minimum deployment target, and then implicitly added the @available checks on the developer's behalf – matching the current experience for system libraries.

8 Likes

I think the current behavior is actually what matches how system frameworks work. The author marks individual APIs if they want to offer different functionality based on availability or they make an entire library available only to client's with a certain deployment target.

No, system frameworks always have all APIs marked with availability, or they're assumed to always be available.

There can be differences in compiling with different deployment targets beyond just availability. In particular, a newer deployment target means the compiler may use optimizations that are only available on newer OSs, or omit metadata that's only used by older OSs. This should be transparent, but in extremely rare cases it can cause detectable behavior change; for example, Objective-C code could be relying on -fobjc-constant-literals actually putting literals in the constant data section of the binary.

But I don't think that should block this change. It might be tricky to implement, but I can't think of any semantic reason why it would be unsound.

2 Likes
Terms of Service

Privacy Policy

Cookie Policy