@@ -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.
@@ -207,6 +217,19 @@ public struct ExplicitModuleBuildHandler {
207
217
)
208
218
}
209
219
220
+ /// Store the output file artifacts for a given module in a JSON file, return the file's path.
221
+ private func serializeModuleDependencies( for moduleId: ModuleDependencyId ,
222
+ dependencyArtifacts: [ SwiftModuleArtifactInfo ]
223
+ ) throws -> AbsolutePath {
224
+ let dependencyFilePath =
225
+ temporaryDirectory. appending ( component: " \( moduleId. moduleName) -dependencies.json " )
226
+ let encoder = JSONEncoder ( )
227
+ encoder. outputFormatting = [ . prettyPrinted]
228
+ let contents = try encoder. encode ( dependencyArtifacts)
229
+ try fileSystem. writeFileContents ( dependencyFilePath, bytes: ByteString ( contents) )
230
+ return dependencyFilePath
231
+ }
232
+
210
233
/// For the specified module, update the given command line flags and inputs
211
234
/// to use explicitly-built module dependencies.
212
235
///
@@ -217,27 +240,43 @@ public struct ExplicitModuleBuildHandler {
217
240
inputs: inout [ TypedVirtualPath ] ,
218
241
commandLine: inout [ Job . ArgTemplate ]
219
242
) throws {
243
+
220
244
// Prohibit the frontend from implicitly building textual modules into binary modules.
221
245
commandLine. appendFlags ( " -disable-implicit-swift-modules " , " -Xcc " , " -Xclang " , " -Xcc " ,
222
246
" -fno-implicit-modules " )
247
+ var swiftDependencyArtifacts : [ SwiftModuleArtifactInfo ] = [ ]
223
248
try addModuleDependencies ( moduleId: moduleId, pcmArgs: pcmArgs, inputs: & inputs,
224
- commandLine: & commandLine)
249
+ commandLine: & commandLine,
250
+ swiftDependencyArtifacts: & swiftDependencyArtifacts)
251
+
252
+ if !swiftDependencyArtifacts. isEmpty {
253
+ let dependencyFile = try serializeModuleDependencies ( for: moduleId,
254
+ dependencyArtifacts: swiftDependencyArtifacts)
255
+ commandLine. appendFlag ( " -explicit-swift-module-map-file " )
256
+ commandLine. appendPath ( dependencyFile)
257
+ inputs. append ( TypedVirtualPath ( file: try VirtualPath ( path: dependencyFile. pathString) ,
258
+ type: . jsonSwiftArtifacts) )
259
+ }
225
260
}
226
261
227
262
/// Add a specific module dependency as an input and a corresponding command
228
263
/// line flag. Dispatches to clang and swift-specific variants.
229
264
mutating private func addModuleDependencies( moduleId: ModuleDependencyId ,
230
265
pcmArgs: [ String ] ,
231
266
inputs: inout [ TypedVirtualPath ] ,
232
- commandLine: inout [ Job . ArgTemplate ] ) throws {
267
+ commandLine: inout [ Job . ArgTemplate ] ,
268
+ swiftDependencyArtifacts: inout [ SwiftModuleArtifactInfo ]
269
+ ) throws {
233
270
for dependencyId in try dependencyGraph. moduleInfo ( of: moduleId) . directDependencies {
234
271
switch dependencyId {
235
272
case . swift:
236
273
try addSwiftModuleDependency ( moduleId: moduleId, dependencyId: dependencyId,
237
- pcmArgs: pcmArgs, inputs: & inputs, commandLine: & commandLine)
274
+ pcmArgs: pcmArgs, inputs: & inputs, commandLine: & commandLine,
275
+ swiftDependencyArtifacts: & swiftDependencyArtifacts)
238
276
case . clang:
239
277
try addClangModuleDependency ( moduleId: moduleId, dependencyId: dependencyId,
240
- pcmArgs: pcmArgs, inputs: & inputs, commandLine: & commandLine)
278
+ pcmArgs: pcmArgs, inputs: & inputs, commandLine: & commandLine,
279
+ swiftDependencyArtifacts: & swiftDependencyArtifacts)
241
280
}
242
281
}
243
282
}
@@ -250,7 +289,9 @@ public struct ExplicitModuleBuildHandler {
250
289
dependencyId: ModuleDependencyId ,
251
290
pcmArgs: [ String ] ,
252
291
inputs: inout [ TypedVirtualPath ] ,
253
- commandLine: inout [ Job . ArgTemplate ] ) throws {
292
+ commandLine: inout [ Job . ArgTemplate ] ,
293
+ swiftDependencyArtifacts: inout [ SwiftModuleArtifactInfo ]
294
+ ) throws {
254
295
// Generate a build job for the dependency module, if not already generated
255
296
if swiftModuleBuildCache [ dependencyId] == nil {
256
297
try genSwiftModuleBuildJob ( moduleId: dependencyId)
@@ -261,13 +302,17 @@ public struct ExplicitModuleBuildHandler {
261
302
let dependencyInfo = try dependencyGraph. moduleInfo ( of: dependencyId)
262
303
let swiftModulePath = TypedVirtualPath ( file: try VirtualPath ( path: dependencyInfo. modulePath) ,
263
304
type: . swiftModule)
264
- commandLine. appendFlags ( " -swift-module-file " )
265
- commandLine. appendPath ( swiftModulePath. file)
266
- inputs. append ( swiftModulePath)
305
+
306
+ // Collect the requried information about this module
307
+ // TODO: add .swiftdoc and .swiftsourceinfo for this module.
308
+ swiftDependencyArtifacts. append (
309
+ SwiftModuleArtifactInfo ( name: dependencyId. moduleName,
310
+ modulePath: swiftModulePath. file. description) )
267
311
268
312
// Process all transitive dependencies as direct
269
- try addModuleDependencies ( moduleId: dependencyId, pcmArgs: pcmArgs, inputs: & inputs,
270
- commandLine: & commandLine)
313
+ try addModuleDependencies ( moduleId: dependencyId, pcmArgs: pcmArgs,
314
+ inputs: & inputs, commandLine: & commandLine,
315
+ swiftDependencyArtifacts: & swiftDependencyArtifacts)
271
316
}
272
317
273
318
/// Add a specific Clang module dependency as an input and a corresponding command
@@ -278,7 +323,9 @@ public struct ExplicitModuleBuildHandler {
278
323
dependencyId: ModuleDependencyId ,
279
324
pcmArgs: [ String ] ,
280
325
inputs: inout [ TypedVirtualPath ] ,
281
- commandLine: inout [ Job . ArgTemplate ] ) throws {
326
+ commandLine: inout [ Job . ArgTemplate ] ,
327
+ swiftDependencyArtifacts: inout [ SwiftModuleArtifactInfo ]
328
+ ) throws {
282
329
// Generate a build job for the dependency module at the given target, if not already generated
283
330
if clangTargetModuleBuildCache [ ( dependencyId, pcmArgs) ] == nil {
284
331
try genClangModuleBuildJob ( moduleId: dependencyId, pcmArgs: pcmArgs)
@@ -302,8 +349,9 @@ public struct ExplicitModuleBuildHandler {
302
349
inputs. append ( clangModuleMapPath)
303
350
304
351
// Process all transitive dependencies as direct
305
- try addModuleDependencies ( moduleId: dependencyId, pcmArgs: pcmArgs, inputs: & inputs,
306
- commandLine: & commandLine)
352
+ try addModuleDependencies ( moduleId: dependencyId, pcmArgs: pcmArgs,
353
+ inputs: & inputs, commandLine: & commandLine,
354
+ swiftDependencyArtifacts: & swiftDependencyArtifacts)
307
355
}
308
356
}
309
357
0 commit comments