You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Documentation/ModuleAliasing.md
+61-12Lines changed: 61 additions & 12 deletions
Original file line number
Diff line number
Diff line change
@@ -31,8 +31,22 @@ Package manifest `swift-game`
31
31
}
32
32
```
33
33
34
+
Package manifest `swift-draw`
35
+
```
36
+
{
37
+
name: "swift-draw",
38
+
products: [
39
+
.library(name: "Utils", targets: ["Utils"]),
40
+
],
41
+
targets: [
42
+
.target(name: "Utils", dependencies: [])
43
+
]
44
+
}
45
+
```
46
+
34
47
Both `swift-draw` and `swift-game` vend modules with the same name `Utils`, thus causing a conflict. To resolve the collision, a new parameter `moduleAliases` can now be used to disambiguate them.
35
48
49
+
Package manifest `App`
36
50
```
37
51
targets: [
38
52
.executableTarget(
@@ -51,6 +65,8 @@ The value for the `moduleAliases` parameter is a dictionary where the key is the
51
65
52
66
To use the aliased module, `App` needs to reference the the new name, i.e. `import GameUtils`. Its existing `import Utils` statement will continue to reference the `Utils` module from package `swift-draw`, as expected.
53
67
68
+
Note that the dependency product names are duplicate, i.e. both have the same name `Utils`, which is by default not allowed. However, this is allowed when module aliasing is used as long as no multiple files with the same product name are created. This means they must all be automatic library types, or at most one of them can be a static library, dylib, an executable, or any other type that creates a file or a directory with the product name.
69
+
54
70
### Example 2
55
71
56
72
`App` imports a module `Utils` from a package `swift-draw`. It wants to add another package dependency `swift-game` and imports a module `Game` vended from the package. The `Game` module imports `Utils` from the same package.
@@ -80,6 +96,7 @@ Similar to Example 1, both packages contain modules with the same name `Utils`,
80
96
81
97
We can use `moduleAliases` again, as follows.
82
98
99
+
Package manifest `App`
83
100
```
84
101
targets: [
85
102
.executableTarget(
@@ -104,45 +121,76 @@ If more aliases need to be defined, they can be added with a comma delimiter, pe
104
121
105
122
## Override Module Aliases
106
123
107
-
The `moduleAliases`defined in a downstream package will override the `moduleAliases` values defined in an upstream package. This may be useful if the upstream aliases themselves result in a conflict.
124
+
If module alias values defined upstream are conflicting downstream, they can be overriden by chaining; add an entry to the `moduleAliases` parameter downstream using the conflicting alias value as a key and provide a unique value.
108
125
109
-
To illustrate, the `swift-game`package is modified to have the following package dependency.
126
+
To illustrate, the `swift-draw` and `swift-game`packages are modified to have the following dependencies and module aliases.
110
127
128
+
Package manifest `swift-draw`
129
+
```
130
+
{
131
+
name: "swift-draw",
132
+
dependencies: [
133
+
.package(url: https://.../a-utils.git),
134
+
.package(url: https://.../b-utils.git),
135
+
],
136
+
products: [
137
+
.library(name: "Draw", targets: ["Draw"]),
138
+
],
139
+
targets: [
140
+
.target(name: "Draw",
141
+
dependencies: [
142
+
.product(name: "Utils",
143
+
package: "a-utils",
144
+
moduleAliases: ["Utils": "FooUtils"]),
145
+
.product(name: "Utils",
146
+
package: "b-utils",
147
+
moduleAliases: ["Utils": "BarUtils"]),
148
+
])
149
+
]
150
+
}
151
+
```
152
+
Package manifest `swift-game`
111
153
```
112
154
{
113
155
name: "swift-game",
114
156
dependencies: [
115
-
.package(url: https://.../swift-utils.git),
157
+
.package(url: https://.../c-utils.git),
158
+
.package(url: https://.../d-utils.git),
116
159
],
117
160
products: [
118
161
.library(name: "Game", targets: ["Game"]),
119
162
],
120
163
targets: [
121
164
.target(name: "Game",
122
165
dependencies: [
123
-
.product(name: "UtilsInSwift",
124
-
package: "swift-utils",
125
-
moduleAliases: ["Utils": "SwiftUtils"]),
166
+
.product(name: "Utils",
167
+
package: "c-utils",
168
+
moduleAliases: ["Utils": "FooUtils"]),
169
+
.product(name: "Utils",
170
+
package: "d-utils",
171
+
moduleAliases: ["Utils": "BazUtils"]),
126
172
])
127
173
]
128
174
}
129
175
```
130
-
The `App` manifest is same as before:
176
+
177
+
Both packages define `FooUtils` as an alias, thus causing a conflict downstream.
178
+
To override it, the `App` manifest can define its own module aliases per below.
131
179
```
132
180
targets: [
133
181
.executableTarget(
134
182
name: "App",
135
183
dependencies: [
136
-
.product(name: "Utils",
137
-
package: "swift-draw"),
184
+
.product(name: "Draw",
185
+
package: "swift-draw",
186
+
moduleAliases: ["FooUtils": "DrawUtils"]),
138
187
.product(name: "Game",
139
188
package: "swift-game",
140
-
moduleAliases: ["Utils": "GameUtils"]),
189
+
moduleAliases: ["FooUtils": "GameUtils"]),
141
190
])
142
191
]
143
192
```
144
-
145
-
The alias `SwiftUtils` defined in `swift-game` will be overridden by the value `GameUtils` defined in `App` for the `Utils` module vended by `swift-utils`. The module will be renamed as `GameUtils` and all of the targets that depend on the module will treat it as `GameUtils`.
193
+
The `Utils` module from package `a-utils` will be renamed as `DrawUtils`, and `Utils` from package `c-utils` will be renamed as `GameUtils`. Each overriden alias will be applied to all of the targets that depend on each module.
146
194
147
195
## Requirements
148
196
@@ -151,3 +199,4 @@ The alias `SwiftUtils` defined in `swift-game` will be overridden by the value `
151
199
* A module being aliased cannot be a prebuilt binary due to the impact on mangling and serialization, i.e. source-based only.
152
200
* A module being aliased should not be passed to a runtime call such as `NSClassFromString(...)` that converts (directly or indirectly) String to a type in a module since such call will fail.
153
201
* If a target mapped to a module being aliased contains resources, they should be asset catalogs, localized strings, or resources that do not require explicit module names.
202
+
* If a product that a module being aliased belongs to has a conflicting name with another product, at most one of the products can be a non-automatic library type.
0 commit comments