Hi @NeoNacho, and sorry for bumping this thread 
However I thought it was better to have your opinion before starting a new thread.
Even though the workaround to use a symlink works (essentially by tricking SPM to see a different path
), it's a bit "sneaky" and I think that this perhaps deserves a better, more explicit solution. I see some scenarios where having multiple "groups" of targets/products can be useful, like:
- a product that has multiple compilation "paths" like the example in the thread (same code, compiled with or without a flag)
- a product made available as variable module configurations: e.g. a single module (
import Foo) vs multiple submodules (import FooBar, import FooBaz, ...)
Point 2 can arguably be seen as a bit of an anti-pattern, but it can still make sense on some cases, like libraries that are transitioning from single module to multi-module and want to provide backwards compatibility or when you simply want to allow multiple setups. I see point 1 as something that can be quite frequent and a legitimate use case.
I understand and agree with the reasoning for enforcing path exclusivity (avoid invalid combinations of imports that could lead to duplicate symbols), but would it make sense to try and have the best of both worlds and be able to create product/target groups that would be mutually exclusive between themselves? Something like:
let package = Package(
name: "Foo",
products: [
.library(
name: "FooSingle",
targets: ["Foo"],
group: "Single" // <-- group tag
),
.library(
name: "Foo",
targets: ["Bar", "Baz"],
group: "Multi" // <-- group tag
),
.library(
name: "FooSingleFlag",
targets: ["FooFlag"],
group: "Flag" // <-- group tag
),
],
targets: [
.target(
name: "Foo",
dependencies: [],
path: ["Sources"],
group: "Single" // <-- group tag
),
.target(
name: "Bar",
dependencies: [],
path: ["Sources/Foo"],
group: "Multi" // <-- group tag
),
.target(
name: "Baz",
dependencies: [],
path: ["Sources/Baz"],
group: "Multi" // <-- group tag
),
.target(
name: "FooFlag",
dependencies: [],
path: ["Sources"],
group: "FooFlag", // <-- group tag
swiftSettings: [.define("FLAG")]
),
]
)
This new group key would allow SPM to perform the exact same checks on path exclusivity (now per group), while allowing multiple groups to co-exist and still preventing users from invalid configuration by forbidding products/targets imports from different groups simultaneously. It's also a purely additive change (I think?), which is always good.
What do you say? If you think this idea is worth exploring I can move this discussion into a proper pitch.
Thanks! 