@@ -45,6 +45,8 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
45
45
/// Whether we are using the integrated driver via libSwiftDriver shared lib
46
46
private let integratedDriver : Bool
47
47
private let mainModuleName : String ?
48
+ private let enableCAS : Bool
49
+ private let swiftScanOracle : InterModuleDependencyOracle
48
50
49
51
/// Clang PCM names contain a hash of the command-line arguments that were used to build them.
50
52
/// We avoid re-running the hash computation with the use of this cache
@@ -55,14 +57,18 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
55
57
56
58
public init ( dependencyGraph: InterModuleDependencyGraph ,
57
59
toolchain: Toolchain ,
60
+ dependencyOracle: InterModuleDependencyOracle ,
58
61
integratedDriver: Bool = true ,
59
- supportsExplicitInterfaceBuild: Bool = false ) throws {
62
+ supportsExplicitInterfaceBuild: Bool = false ,
63
+ enableCAS: Bool = false ) throws {
60
64
self . dependencyGraph = dependencyGraph
61
65
self . toolchain = toolchain
66
+ self . swiftScanOracle = dependencyOracle
62
67
self . integratedDriver = integratedDriver
63
68
self . mainModuleName = dependencyGraph. mainModuleName
64
69
self . reachabilityMap = try dependencyGraph. computeTransitiveClosure ( )
65
70
self . supportsExplicitInterfaceBuild = supportsExplicitInterfaceBuild
71
+ self . enableCAS = enableCAS
66
72
}
67
73
68
74
/// Generate build jobs for all dependencies of the main module.
@@ -136,7 +142,8 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
136
142
// Resolve all dependency module inputs for this Swift module
137
143
try resolveExplicitModuleDependencies ( moduleId: moduleId,
138
144
inputs: & inputs,
139
- commandLine: & commandLine)
145
+ commandLine: & commandLine,
146
+ isMainModule: false )
140
147
141
148
// Build the .swiftinterfaces file using a list of command line options specified in the
142
149
// `details` field.
@@ -192,7 +199,8 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
192
199
193
200
// Resolve all dependency module inputs for this Clang module
194
201
try resolveExplicitModuleDependencies ( moduleId: moduleId, inputs: & inputs,
195
- commandLine: & commandLine)
202
+ commandLine: & commandLine,
203
+ isMainModule: false )
196
204
197
205
let moduleMapPath = moduleDetails. moduleMapPath. path
198
206
let modulePCMPath = moduleInfo. modulePath
@@ -221,7 +229,8 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
221
229
/// to use explicitly-built module dependencies.
222
230
private mutating func resolveExplicitModuleDependencies( moduleId: ModuleDependencyId ,
223
231
inputs: inout [ TypedVirtualPath ] ,
224
- commandLine: inout [ Job . ArgTemplate ] ) throws {
232
+ commandLine: inout [ Job . ArgTemplate ] ,
233
+ isMainModule: Bool ) throws {
225
234
// Prohibit the frontend from implicitly building textual modules into binary modules.
226
235
var swiftDependencyArtifacts : [ SwiftModuleArtifactInfo ] = [ ]
227
236
var clangDependencyArtifacts : [ ClangModuleArtifactInfo ] = [ ]
@@ -256,15 +265,24 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
256
265
257
266
// Swift Main Module dependencies are passed encoded in a JSON file as described by
258
267
// SwiftModuleArtifactInfo
259
- if moduleId. moduleName == mainModuleName {
260
- let dependencyFile =
261
- try serializeModuleDependencies ( for: moduleId,
262
- swiftDependencyArtifacts: swiftDependencyArtifacts,
263
- clangDependencyArtifacts: clangDependencyArtifacts)
264
- commandLine. appendFlag ( " -explicit-swift-module-map-file " )
265
- commandLine. appendPath ( dependencyFile)
266
- inputs. append ( TypedVirtualPath ( file: dependencyFile. intern ( ) ,
267
- type: . jsonSwiftArtifacts) )
268
+ if isMainModule {
269
+ if enableCAS {
270
+ let dependencyFile =
271
+ try serializeModuleDependenciesToCAS ( for: moduleId,
272
+ swiftDependencyArtifacts: swiftDependencyArtifacts,
273
+ clangDependencyArtifacts: clangDependencyArtifacts)
274
+ commandLine. appendFlag ( " -explicit-swift-module-map-file " )
275
+ commandLine. appendFlag ( dependencyFile)
276
+ } else {
277
+ let dependencyFile =
278
+ try serializeModuleDependencies ( for: moduleId,
279
+ swiftDependencyArtifacts: swiftDependencyArtifacts,
280
+ clangDependencyArtifacts: clangDependencyArtifacts)
281
+ commandLine. appendFlag ( " -explicit-swift-module-map-file " )
282
+ commandLine. appendPath ( dependencyFile)
283
+ inputs. append ( TypedVirtualPath ( file: dependencyFile. intern ( ) ,
284
+ type: . jsonSwiftArtifacts) )
285
+ }
268
286
}
269
287
}
270
288
@@ -280,13 +298,15 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
280
298
let isFramework : Bool
281
299
swiftModulePath = . init( file: dependencyInfo. modulePath. path,
282
300
type: . swiftModule)
283
- isFramework = try dependencyGraph. swiftModuleDetails ( of: dependencyId) . isFramework ?? false
301
+ let swiftModuleDetails = try dependencyGraph. swiftModuleDetails ( of: dependencyId)
302
+ isFramework = swiftModuleDetails. isFramework ?? false
284
303
// Accumulate the required information about this dependency
285
304
// TODO: add .swiftdoc and .swiftsourceinfo for this module.
286
305
swiftDependencyArtifacts. append (
287
306
SwiftModuleArtifactInfo ( name: dependencyId. moduleName,
288
307
modulePath: TextualVirtualPath ( path: swiftModulePath. fileHandle) ,
289
- isFramework: isFramework) )
308
+ isFramework: isFramework,
309
+ moduleCacheKey: swiftModuleDetails. moduleCacheKey) )
290
310
case . clang:
291
311
let dependencyInfo = try dependencyGraph. moduleInfo ( of: dependencyId)
292
312
let dependencyClangModuleDetails =
@@ -295,7 +315,8 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
295
315
clangDependencyArtifacts. append (
296
316
ClangModuleArtifactInfo ( name: dependencyId. moduleName,
297
317
modulePath: TextualVirtualPath ( path: dependencyInfo. modulePath. path) ,
298
- moduleMapPath: dependencyClangModuleDetails. moduleMapPath) )
318
+ moduleMapPath: dependencyClangModuleDetails. moduleMapPath,
319
+ moduleCacheKey: dependencyClangModuleDetails. moduleCacheKey) )
299
320
case . swiftPrebuiltExternal:
300
321
let prebuiltModuleDetails = try dependencyGraph. swiftPrebuiltDetails ( of: dependencyId)
301
322
let compiledModulePath = prebuiltModuleDetails. compiledModulePath
@@ -308,7 +329,8 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
308
329
SwiftModuleArtifactInfo ( name: dependencyId. moduleName,
309
330
modulePath: TextualVirtualPath ( path: swiftModulePath. fileHandle) ,
310
331
headerDependencies: prebuiltModuleDetails. headerDependencyPaths,
311
- isFramework: isFramework) )
332
+ isFramework: isFramework,
333
+ moduleCacheKey: prebuiltModuleDetails. moduleCacheKey) )
312
334
case . swiftPlaceholder:
313
335
fatalError ( " Unresolved placeholder dependencies at planning stage: \( dependencyId) of \( moduleId) " )
314
336
}
@@ -354,24 +376,25 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
354
376
public mutating func resolveMainModuleDependencies( inputs: inout [ TypedVirtualPath ] ,
355
377
commandLine: inout [ Job . ArgTemplate ] ) throws {
356
378
let mainModuleId : ModuleDependencyId = . swift( dependencyGraph. mainModuleName)
379
+
380
+ let mainModuleDetails = try dependencyGraph. swiftModuleDetails ( of: mainModuleId)
381
+ if let additionalArgs = mainModuleDetails. commandLine {
382
+ additionalArgs. forEach { commandLine. appendFlag ( $0) }
383
+ }
357
384
commandLine. appendFlags ( " -disable-implicit-swift-modules " ,
358
385
" -Xcc " , " -fno-implicit-modules " ,
359
386
" -Xcc " , " -fno-implicit-module-maps " )
360
387
try resolveExplicitModuleDependencies ( moduleId: mainModuleId,
361
388
inputs: & inputs,
362
- commandLine: & commandLine)
389
+ commandLine: & commandLine,
390
+ isMainModule: true )
363
391
}
364
392
365
393
/// Resolve all module dependencies of the main module and add them to the lists of
366
394
/// inputs and command line flags.
367
395
public mutating func resolveBridgingHeaderDependencies( inputs: inout [ TypedVirtualPath ] ,
368
396
commandLine: inout [ Job . ArgTemplate ] ) throws {
369
397
let mainModuleId : ModuleDependencyId = . swift( dependencyGraph. mainModuleName)
370
- // Prohibit the frontend from implicitly building textual modules into binary modules.
371
- commandLine. appendFlags ( " -disable-implicit-swift-modules " ,
372
- " -Xcc " , " -fno-implicit-modules " ,
373
- " -Xcc " , " -fno-implicit-module-maps " )
374
-
375
398
var swiftDependencyArtifacts : [ SwiftModuleArtifactInfo ] = [ ]
376
399
var clangDependencyArtifacts : [ ClangModuleArtifactInfo ] = [ ]
377
400
let mainModuleDetails = try dependencyGraph. swiftModuleDetails ( of: mainModuleId)
@@ -409,14 +432,34 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
409
432
inputs. append ( clangModuleMapPath)
410
433
}
411
434
412
- let dependencyFile =
413
- try serializeModuleDependencies ( for: mainModuleId,
414
- swiftDependencyArtifacts: swiftDependencyArtifacts,
415
- clangDependencyArtifacts: clangDependencyArtifacts)
416
- commandLine. appendFlag ( " -explicit-swift-module-map-file " )
417
- commandLine. appendPath ( dependencyFile)
418
- inputs. append ( TypedVirtualPath ( file: dependencyFile. intern ( ) ,
419
- type: . jsonSwiftArtifacts) )
435
+ // Return if depscanner provided build commands.
436
+ if enableCAS, let scannerPCHArgs = mainModuleDetails. bridgingPchCommandLine {
437
+ scannerPCHArgs. forEach { commandLine. appendFlag ( $0) }
438
+ return
439
+ }
440
+
441
+ // Prohibit the frontend from implicitly building textual modules into binary modules.
442
+ commandLine. appendFlags ( " -disable-implicit-swift-modules " ,
443
+ " -Xcc " , " -fno-implicit-modules " ,
444
+ " -Xcc " , " -fno-implicit-module-maps " )
445
+
446
+ if enableCAS {
447
+ let dependencyFile =
448
+ try serializeModuleDependenciesToCAS ( for: mainModuleId,
449
+ swiftDependencyArtifacts: swiftDependencyArtifacts,
450
+ clangDependencyArtifacts: clangDependencyArtifacts)
451
+ commandLine. appendFlag ( " -explicit-swift-module-map-file " )
452
+ commandLine. appendFlag ( dependencyFile)
453
+ } else {
454
+ let dependencyFile =
455
+ try serializeModuleDependencies ( for: mainModuleId,
456
+ swiftDependencyArtifacts: swiftDependencyArtifacts,
457
+ clangDependencyArtifacts: clangDependencyArtifacts)
458
+ commandLine. appendFlag ( " -explicit-swift-module-map-file " )
459
+ commandLine. appendPath ( dependencyFile)
460
+ inputs. append ( TypedVirtualPath ( file: dependencyFile. intern ( ) ,
461
+ type: . jsonSwiftArtifacts) )
462
+ }
420
463
}
421
464
422
465
/// Store the output file artifacts for a given module in a JSON file, return the file's path.
@@ -433,6 +476,22 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
433
476
return VirtualPath . createUniqueTemporaryFileWithKnownContents ( . init( " \( moduleId. moduleName) -dependencies.json " ) , contents)
434
477
}
435
478
479
+ private func serializeModuleDependenciesToCAS( for moduleId: ModuleDependencyId ,
480
+ swiftDependencyArtifacts: [ SwiftModuleArtifactInfo ] ,
481
+ clangDependencyArtifacts: [ ClangModuleArtifactInfo ]
482
+ ) throws -> String {
483
+ // The module dependency map in CAS needs to be stable.
484
+ // Sort the dependencies by name.
485
+ let allDependencyArtifacts : [ ModuleDependencyArtifactInfo ] =
486
+ swiftDependencyArtifacts. sorted ( ) . map { ModuleDependencyArtifactInfo . swift ( $0) } +
487
+ clangDependencyArtifacts. sorted ( ) . map { ModuleDependencyArtifactInfo . clang ( $0) }
488
+ let encoder = JSONEncoder ( )
489
+ // Use sorted key to ensure the order of the keys is stable.
490
+ encoder. outputFormatting = [ . prettyPrinted, . sortedKeys]
491
+ let contents = try encoder. encode ( allDependencyArtifacts)
492
+ return try swiftScanOracle. store ( data: contents)
493
+ }
494
+
436
495
private func getPCMHashParts( pcmArgs: [ String ] , contextHash: String ) -> [ String ] {
437
496
var results : [ String ] = [ ]
438
497
results. append ( contextHash)
0 commit comments