A project to study Swift Package Manager dependency behavior across different Swift language versions.
This project uses a diamond dependency structure to test Swift language version compatibility:
Main App
|
v
PackageA
/ \
v v
PackageACore PackageB
↑ |
| v
| PackageBCore
| |
+---------+
Dependency relationships:
- Main App depends on PackageA
- PackageA depends on PackageACore (internal target) and PackageB
- PackageB depends on PackageBCore (internal target)
- PackageBCore depends on PackageACore
This creates a diamond where PackageACore is reached through two paths:
- Main App → PackageA → PackageACore
- Main App → PackageA → PackageB → PackageBCore → PackageACore
| Package | Swift Tools Version | Swift Language Mode |
|---|---|---|
| PackageA | 6.0 | v6 |
| PackageB | 6.0 | v5 |
| PackageC | 5.9 | (default) |
When setting PackageA to Swift 5 language mode (swiftLanguageModes: [.v5]) while its dependencies (PackageB) remain on Swift 6, the test target fails with:
PackageATests: 2 issues
- 5 duplicate symbols
- Linker command failed with exit code 1
Swift 6 has stricter module boundaries and symbol isolation by default. When dropping to Swift 5 mode, symbols that were properly isolated in Swift 6 may be exported/visible in ways that cause duplication at link time.