@@ -31,9 +31,19 @@ public struct ExplicitModuleBuildHandler {
31
31
/// The toolchain to be used for frontend job generation.
32
32
private let toolchain : Toolchain
33
33
34
- public init ( dependencyGraph: InterModuleDependencyGraph , toolchain: Toolchain ) throws {
34
+ /// The file system which we should interact with.
35
+ private let fileSystem : FileSystem
36
+
37
+ /// Path to the directory that will contain the temporary files.
38
+ /// e.g. Explicit Swift module artifact files
39
+ private let temporaryDirectory : AbsolutePath
40
+
41
+ public init ( dependencyGraph: InterModuleDependencyGraph , toolchain: Toolchain ,
42
+ fileSystem: FileSystem ) throws {
35
43
self . dependencyGraph = dependencyGraph
36
44
self . toolchain = toolchain
45
+ self . fileSystem = fileSystem
46
+ self . temporaryDirectory = try determineTempDirectory ( )
37
47
}
38
48
39
49
/// Generate build jobs for all dependencies of the main module.
@@ -97,17 +107,10 @@ public struct ExplicitModuleBuildHandler {
97
107
/// - Generate Job: S1
98
108
///
99
109
mutating public func generateExplicitModuleDependenciesBuildJobs( ) throws -> [ Job ] {
100
- for moduleId in dependencyGraph. mainModule. directDependencies {
101
- switch moduleId {
102
- case . swift:
103
- try genSwiftModuleBuildJob ( moduleId: moduleId)
104
- case . clang:
105
- try genClangModuleBuildJob ( moduleId: moduleId,
106
- pcmArgs: try dependencyGraph. swiftModulePCMArgs (
107
- of: . swift( dependencyGraph. mainModuleName) ) )
108
- }
109
- }
110
-
110
+ var mainModuleInputs : [ TypedVirtualPath ] = [ ]
111
+ var mainModuleCommandLine : [ Job . ArgTemplate ] = [ ]
112
+ try resolveMainModuleDependencies ( inputs: & mainModuleInputs,
113
+ commandLine: & mainModuleCommandLine)
111
114
return Array ( swiftModuleBuildCache. values) + clangTargetModuleBuildCache. allJobs
112
115
}
113
116
@@ -167,7 +170,6 @@ public struct ExplicitModuleBuildHandler {
167
170
mutating private func genClangModuleBuildJob( moduleId: ModuleDependencyId ,
168
171
pcmArgs: [ String ] ) throws {
169
172
let moduleInfo = try dependencyGraph. moduleInfo ( of: moduleId)
170
-
171
173
var inputs : [ TypedVirtualPath ] = [ ]
172
174
var outputs : [ TypedVirtualPath ] = [ ]
173
175
var commandLine : [ Job . ArgTemplate ] = [ ]
@@ -207,6 +209,19 @@ public struct ExplicitModuleBuildHandler {
207
209
)
208
210
}
209
211
212
+ /// Store the output file artifacts for a given module in a JSON file, return the file's path.
213
+ private func serializeModuleDependencies( for moduleId: ModuleDependencyId ,
214
+ dependencyArtifacts: [ SwiftModuleArtifactInfo ]
215
+ ) throws -> AbsolutePath {
216
+ let dependencyFilePath =
217
+ temporaryDirectory. appending ( component: " \( moduleId. moduleName) -dependencies.json " )
218
+ let encoder = JSONEncoder ( )
219
+ encoder. outputFormatting = [ . prettyPrinted]
220
+ let contents = try encoder. encode ( dependencyArtifacts)
221
+ try fileSystem. writeFileContents ( dependencyFilePath, bytes: ByteString ( contents) )
222
+ return dependencyFilePath
223
+ }
224
+
210
225
/// For the specified module, update the given command line flags and inputs
211
226
/// to use explicitly-built module dependencies.
212
227
///
@@ -220,24 +235,45 @@ public struct ExplicitModuleBuildHandler {
220
235
// Prohibit the frontend from implicitly building textual modules into binary modules.
221
236
commandLine. appendFlags ( " -disable-implicit-swift-modules " , " -Xcc " , " -Xclang " , " -Xcc " ,
222
237
" -fno-implicit-modules " )
238
+ var swiftDependencyArtifacts : [ SwiftModuleArtifactInfo ] = [ ]
223
239
try addModuleDependencies ( moduleId: moduleId, pcmArgs: pcmArgs, inputs: & inputs,
224
- commandLine: & commandLine)
240
+ commandLine: & commandLine,
241
+ swiftDependencyArtifacts: & swiftDependencyArtifacts)
242
+
243
+ if !swiftDependencyArtifacts. isEmpty {
244
+ let dependencyFile = try serializeModuleDependencies ( for: moduleId,
245
+ dependencyArtifacts: swiftDependencyArtifacts)
246
+ commandLine. appendFlag ( " -explicit-swift-module-map-file " )
247
+ commandLine. appendPath ( dependencyFile)
248
+ inputs. append ( TypedVirtualPath ( file: try VirtualPath ( path: dependencyFile. pathString) ,
249
+ type: . jsonSwiftArtifacts) )
250
+ // Each individual moduel binary is still an "input" to ensure the build system gets the
251
+ // order correctly.
252
+ for dependencyModule in swiftDependencyArtifacts {
253
+ inputs. append ( TypedVirtualPath ( file: try VirtualPath ( path: dependencyModule. modulePath) ,
254
+ type: . swiftModule) )
255
+ }
256
+ }
225
257
}
226
258
227
259
/// Add a specific module dependency as an input and a corresponding command
228
260
/// line flag. Dispatches to clang and swift-specific variants.
229
261
mutating private func addModuleDependencies( moduleId: ModuleDependencyId ,
230
262
pcmArgs: [ String ] ,
231
263
inputs: inout [ TypedVirtualPath ] ,
232
- commandLine: inout [ Job . ArgTemplate ] ) throws {
264
+ commandLine: inout [ Job . ArgTemplate ] ,
265
+ swiftDependencyArtifacts: inout [ SwiftModuleArtifactInfo ]
266
+ ) throws {
233
267
for dependencyId in try dependencyGraph. moduleInfo ( of: moduleId) . directDependencies {
234
268
switch dependencyId {
235
269
case . swift:
236
270
try addSwiftModuleDependency ( moduleId: moduleId, dependencyId: dependencyId,
237
- pcmArgs: pcmArgs, inputs: & inputs, commandLine: & commandLine)
271
+ pcmArgs: pcmArgs, inputs: & inputs, commandLine: & commandLine,
272
+ swiftDependencyArtifacts: & swiftDependencyArtifacts)
238
273
case . clang:
239
274
try addClangModuleDependency ( moduleId: moduleId, dependencyId: dependencyId,
240
- pcmArgs: pcmArgs, inputs: & inputs, commandLine: & commandLine)
275
+ pcmArgs: pcmArgs, inputs: & inputs, commandLine: & commandLine,
276
+ swiftDependencyArtifacts: & swiftDependencyArtifacts)
241
277
}
242
278
}
243
279
}
@@ -250,7 +286,9 @@ public struct ExplicitModuleBuildHandler {
250
286
dependencyId: ModuleDependencyId ,
251
287
pcmArgs: [ String ] ,
252
288
inputs: inout [ TypedVirtualPath ] ,
253
- commandLine: inout [ Job . ArgTemplate ] ) throws {
289
+ commandLine: inout [ Job . ArgTemplate ] ,
290
+ swiftDependencyArtifacts: inout [ SwiftModuleArtifactInfo ]
291
+ ) throws {
254
292
// Generate a build job for the dependency module, if not already generated
255
293
if swiftModuleBuildCache [ dependencyId] == nil {
256
294
try genSwiftModuleBuildJob ( moduleId: dependencyId)
@@ -261,13 +299,17 @@ public struct ExplicitModuleBuildHandler {
261
299
let dependencyInfo = try dependencyGraph. moduleInfo ( of: dependencyId)
262
300
let swiftModulePath = TypedVirtualPath ( file: try VirtualPath ( path: dependencyInfo. modulePath) ,
263
301
type: . swiftModule)
264
- commandLine. appendFlags ( " -swift-module-file " )
265
- commandLine. appendPath ( swiftModulePath. file)
266
- inputs. append ( swiftModulePath)
302
+
303
+ // Collect the requried information about this module
304
+ // TODO: add .swiftdoc and .swiftsourceinfo for this module.
305
+ swiftDependencyArtifacts. append (
306
+ SwiftModuleArtifactInfo ( name: dependencyId. moduleName,
307
+ modulePath: swiftModulePath. file. description) )
267
308
268
309
// Process all transitive dependencies as direct
269
- try addModuleDependencies ( moduleId: dependencyId, pcmArgs: pcmArgs, inputs: & inputs,
270
- commandLine: & commandLine)
310
+ try addModuleDependencies ( moduleId: dependencyId, pcmArgs: pcmArgs,
311
+ inputs: & inputs, commandLine: & commandLine,
312
+ swiftDependencyArtifacts: & swiftDependencyArtifacts)
271
313
}
272
314
273
315
/// Add a specific Clang module dependency as an input and a corresponding command
@@ -278,7 +320,9 @@ public struct ExplicitModuleBuildHandler {
278
320
dependencyId: ModuleDependencyId ,
279
321
pcmArgs: [ String ] ,
280
322
inputs: inout [ TypedVirtualPath ] ,
281
- commandLine: inout [ Job . ArgTemplate ] ) throws {
323
+ commandLine: inout [ Job . ArgTemplate ] ,
324
+ swiftDependencyArtifacts: inout [ SwiftModuleArtifactInfo ]
325
+ ) throws {
282
326
// Generate a build job for the dependency module at the given target, if not already generated
283
327
if clangTargetModuleBuildCache [ ( dependencyId, pcmArgs) ] == nil {
284
328
try genClangModuleBuildJob ( moduleId: dependencyId, pcmArgs: pcmArgs)
@@ -302,8 +346,9 @@ public struct ExplicitModuleBuildHandler {
302
346
inputs. append ( clangModuleMapPath)
303
347
304
348
// Process all transitive dependencies as direct
305
- try addModuleDependencies ( moduleId: dependencyId, pcmArgs: pcmArgs, inputs: & inputs,
306
- commandLine: & commandLine)
349
+ try addModuleDependencies ( moduleId: dependencyId, pcmArgs: pcmArgs,
350
+ inputs: & inputs, commandLine: & commandLine,
351
+ swiftDependencyArtifacts: & swiftDependencyArtifacts)
307
352
}
308
353
}
309
354
0 commit comments