This should work in theory. I've seen a number of packages do something like this to support Android, although I haven't seen any that have used traits to conditionally enable it yet.
Under what circumstances if the OpenCombineSchedulers trait enabled? If you manually set it to default to true, does it work?
Yes, that's exactly the problem. The Package.swift is evaluated on the host platform. It would be nice if a trait could be conditionally enabled based on the target platform, but that isn't currently supported.
Why are you gating the dependency on both the traits: ["OpenCombineSchedulers"] and .when(platforms: [.linux, .android]) conditions? Wouldn't just the platform condition be sufficient?
It’s not my own package, but one from point-free that I am trying to get to build on Android. It’s the ‘combine-schedulers’ package which is a dependency of ‘swift-dependencies’ which is my actual goal.
I tried removing the trait, just keeping the platforms, but for some reason it still does not resolve the OpenCombine package with my build command.
For now my workaround is to make a branch with no conditions on the package.
A word of caution, though: in cases when the CI testing is run from Linux, then the original gating of the dependency on #if !canImport(Darwin)would happen to work. But it would still break when cross-compiling from a macOS host.
A word of caution, though: in cases when the CI testing is run from Linux, then the original gating of the dependency on #if !canImport(Darwin)would happen to work. But it would still break when cross-compiling from a macOS host.
In general, the package manifest by design has no idea what platform you’re building for. This allows us to use the same package resolution to build for multiple platforms. That is why we have the platform conditionals. And, we should really look to make sure they’re sufficiently expressive (e.g. what about conditional on a specific Android API level?)
Using traits to represent platforms is another anti-pattern I’ve seen. Traits are supposed to represent optional features in a package. They are resolved during package resolution so if you change traits, you end up with a different package semantically. And that comes back to the previous point. If there is something platform-y you want to accomplish and feel pulled to use traits, let us know so we can fix it at the right spot in the architecture.
One thing I had been hopeful with traits would be the possibility of excluding a package dependency altogether based on the trait. That, along with the ability to enable/disable a trait based on the platform, would make it so people who build pointfreeco libraries (like TCA) would avoid having to see "OpenCombine" at all in their Xcode dependencies (which, believe it or not, is something that does bother people who are cautious about their dependencies, even when they are aware that the dependency isn't actually used for their target platform).
There has been work in that direction. It might be in 6.3? But, yes, we often get feedback about SwiftPM downloading too many dependencies when not needed and we have an eye on that.