@@ -45,7 +45,7 @@ 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
48
+ private let cas : SwiftScanCAS ?
49
49
private let swiftScanOracle : InterModuleDependencyOracle
50
50
51
51
/// Clang PCM names contain a hash of the command-line arguments that were used to build them.
@@ -60,15 +60,15 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
60
60
dependencyOracle: InterModuleDependencyOracle ,
61
61
integratedDriver: Bool = true ,
62
62
supportsExplicitInterfaceBuild: Bool = false ,
63
- enableCAS : Bool = false ) throws {
63
+ cas : SwiftScanCAS ? = nil ) throws {
64
64
self . dependencyGraph = dependencyGraph
65
65
self . toolchain = toolchain
66
66
self . swiftScanOracle = dependencyOracle
67
67
self . integratedDriver = integratedDriver
68
68
self . mainModuleName = dependencyGraph. mainModuleName
69
69
self . reachabilityMap = try dependencyGraph. computeTransitiveClosure ( )
70
70
self . supportsExplicitInterfaceBuild = supportsExplicitInterfaceBuild
71
- self . enableCAS = enableCAS
71
+ self . cas = cas
72
72
}
73
73
74
74
/// Supports resolving bridging header pch command from swiftScan.
@@ -136,9 +136,6 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
136
136
for moduleId in swiftDependencies {
137
137
let moduleInfo = try dependencyGraph. moduleInfo ( of: moduleId)
138
138
var inputs : [ TypedVirtualPath ] = [ ]
139
- let outputs : [ TypedVirtualPath ] = [
140
- TypedVirtualPath ( file: moduleInfo. modulePath. path, type: . swiftModule)
141
- ]
142
139
var commandLine : [ Job . ArgTemplate ] = [ ]
143
140
// First, take the command line options provided in the dependency information
144
141
let moduleDetails = try dependencyGraph. swiftModuleDetails ( of: moduleId)
@@ -155,9 +152,14 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
155
152
throw Driver . Error. malformedModuleDependency ( moduleId. moduleName,
156
153
" no `moduleInterfacePath` object " )
157
154
}
158
- inputs. append ( TypedVirtualPath ( file: moduleInterfacePath. path,
159
- type: . swiftInterface) )
160
155
156
+ let inputInterfacePath = TypedVirtualPath ( file: moduleInterfacePath. path, type: . swiftInterface)
157
+ inputs. append ( inputInterfacePath)
158
+ let outputModulePath = TypedVirtualPath ( file: moduleInfo. modulePath. path, type: . swiftModule)
159
+ let outputs = [ outputModulePath]
160
+
161
+ // TODO: Add diagnostics for explicit module build?
162
+ let cacheKeys = [ Job . OutputSpec ( input: inputInterfacePath, output: outputModulePath) : moduleDetails. moduleCacheKey]
161
163
// Add precompiled module candidates, if present
162
164
if let compiledCandidateList = moduleDetails. compiledModuleCandidates {
163
165
for compiledCandidate in compiledCandidateList {
@@ -173,7 +175,8 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
173
175
commandLine: commandLine,
174
176
inputs: inputs,
175
177
primaryInputs: [ ] ,
176
- outputs: outputs
178
+ outputs: outputs,
179
+ outputCacheKeys: cacheKeys
177
180
) )
178
181
}
179
182
return jobs
@@ -205,15 +208,17 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
205
208
try resolveExplicitModuleDependencies ( moduleId: moduleId, inputs: & inputs,
206
209
commandLine: & commandLine)
207
210
208
- let moduleMapPath = moduleDetails. moduleMapPath. path
209
- let modulePCMPath = moduleInfo. modulePath
210
- outputs. append ( TypedVirtualPath ( file : modulePCMPath. path , type : . pcm ) )
211
+ let moduleMapPath = TypedVirtualPath ( file : moduleDetails. moduleMapPath. path, type : . clangModuleMap )
212
+ let modulePCMPath = TypedVirtualPath ( file : moduleInfo. modulePath. path , type : . pcm )
213
+ outputs. append ( modulePCMPath)
211
214
212
215
// The only required input is the .modulemap for this module.
213
216
// Command line options in the dependency scanner output will include the
214
217
// required modulemap, so here we must only add it to the list of inputs.
215
- inputs. append ( TypedVirtualPath ( file: moduleMapPath,
216
- type: . clangModuleMap) )
218
+ inputs. append ( moduleMapPath)
219
+
220
+ // TODO: Add diagnostics for explicit module build?
221
+ let cacheKeys = [ Job . OutputSpec ( input: moduleMapPath, output: modulePCMPath) : moduleDetails. moduleCacheKey]
217
222
218
223
jobs. append ( Job (
219
224
moduleName: moduleId. moduleName,
@@ -222,7 +227,8 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
222
227
commandLine: commandLine,
223
228
inputs: inputs,
224
229
primaryInputs: [ ] ,
225
- outputs: outputs
230
+ outputs: outputs,
231
+ outputCacheKeys: cacheKeys
226
232
) )
227
233
}
228
234
return jobs
@@ -247,7 +253,7 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
247
253
type: . swiftModule) )
248
254
249
255
let prebuiltHeaderDependencyPaths = dependencyModule. prebuiltHeaderDependencyPaths ?? [ ]
250
- if enableCAS && !prebuiltHeaderDependencyPaths. isEmpty {
256
+ if cas != nil && !prebuiltHeaderDependencyPaths. isEmpty {
251
257
throw Driver . Error. unsupportedConfigurationForCaching ( " module \( dependencyModule. moduleName) has prebuilt header dependency " )
252
258
}
253
259
@@ -277,9 +283,9 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
277
283
try serializeModuleDependencies ( for: moduleId,
278
284
swiftDependencyArtifacts: swiftDependencyArtifacts,
279
285
clangDependencyArtifacts: clangDependencyArtifacts)
280
- if enableCAS {
286
+ if let cas = self . cas {
281
287
// When using a CAS, write JSON into CAS and pass the ID on command-line.
282
- let casID = try swiftScanOracle . store ( data: dependencyFileContent)
288
+ let casID = try cas . store ( data: dependencyFileContent)
283
289
commandLine. appendFlag ( " -explicit-swift-module-map-file " )
284
290
commandLine. appendFlag ( casID)
285
291
} else {
@@ -445,7 +451,7 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
445
451
return
446
452
}
447
453
448
- assert ( !enableCAS , " Caching build should always return command-line from scanner " )
454
+ assert ( cas == nil , " Caching build should always return command-line from scanner " )
449
455
// Prohibit the frontend from implicitly building textual modules into binary modules.
450
456
commandLine. appendFlags ( " -disable-implicit-swift-modules " ,
451
457
" -Xcc " , " -fno-implicit-modules " ,
@@ -465,6 +471,20 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
465
471
type: . jsonSwiftArtifacts) )
466
472
}
467
473
474
+ private func computeOutputCacheKey( commandLine: [ Job . ArgTemplate ] ,
475
+ cacheSpecs: [ Job . OutputSpec ] ) throws -> [ Job . OutputSpec : String ? ] {
476
+ return try cacheSpecs. reduce ( into: [ : ] ) { keys, spec in
477
+ if let cas = self . cas, spec. output. type. supportCaching {
478
+ keys [ spec] = try swiftScanOracle. computeCacheKeyForOutput ( cas: cas,
479
+ kind: spec. output. type,
480
+ commandLine: commandLine,
481
+ input: spec. input. file. intern ( ) )
482
+ } else {
483
+ keys [ spec] = nil
484
+ }
485
+ }
486
+ }
487
+
468
488
/// Serialize the output file artifacts for a given module in JSON format.
469
489
private func serializeModuleDependencies( for moduleId: ModuleDependencyId ,
470
490
swiftDependencyArtifacts: [ SwiftModuleArtifactInfo ] ,
0 commit comments