Sharing sources between different targets

I would like to have the following structure:

Sources/Target1/main.swift
Sources/Target2/main.swift
Sources/Shared/Shared.swift

If in Package.swift if I configure Target1 to use Sources/Target1 and Sources/Shared, and Target2 to use Sources/Target2 and Sources/Shared, I get an error that the same source is present in 2 different targets, and thus I can't generate an Xcode project.

Is there any reason for this limitation? I can understand that the ideal setup would be to create a new Shared target and make that as a dependency of Target1 and Target2, but sadly the Shared code is generated, and it doesn't include the appropriate visibility modifiers for the classes to be accessible by dependents.

My workaround is generating the files into each of Target1 and Target2, but this is obviously way dirtier than sharing the sources between multiple targets.

I think you can create symlinks in the targets to share the files.

That's another valid workaround, but I'm still intrigued on the original limitation

IIRC the idea was to prevent users from accidentally sharing source files between targets.

1 Like

Why is that a bad thing? Is it to prevent prevent people from shooting themselves in the foot because it could lead to duplicate symbol errors if not done correctly?

Yeah, it can create different types of build issues. You can end up mixing Swift and C sources which SwiftPM can't even handle, or it can lead to duplicate symbols if you mix two C targets and try to form a product with those targets, or the target dependencies (imports/includes) may not be available in one of the target.

Just to note this caused us an issue too. We needed to compile the same source twice with different Swift flags. Using symlinks causes problems with saving etc in Xcode my colleague informs me.