@@ -75,6 +75,7 @@ extension Driver {
75
75
break
76
76
}
77
77
78
+ let jobNeedPathRemap : Bool
78
79
// If in ExplicitModuleBuild mode and the dependency graph has been computed, add module
79
80
// dependencies.
80
81
// May also be used for generation of the dependency graph itself in ExplicitModuleBuild mode.
@@ -83,17 +84,21 @@ extension Driver {
83
84
switch kind {
84
85
case . generatePCH:
85
86
try addExplicitPCHBuildArguments ( inputs: & inputs, commandLine: & commandLine)
87
+ jobNeedPathRemap = true
86
88
case . compile, . emitModule, . interpret, . verifyModuleInterface:
87
89
try addExplicitModuleBuildArguments ( inputs: & inputs, commandLine: & commandLine)
90
+ jobNeedPathRemap = true
88
91
case . backend, . mergeModule, . compileModuleFromInterface,
89
92
. generatePCM, . dumpPCM, . repl, . printTargetInfo,
90
93
. versionRequest, . autolinkExtract, . generateDSYM,
91
94
. help, . link, . verifyDebugInfo, . scanDependencies,
92
95
. emitSupportedFeatures, . moduleWrap,
93
96
. generateAPIBaseline, . generateABIBaseline, . compareAPIBaseline,
94
97
. compareABIBaseline:
95
- break // Do not support creating from dependency scanner output.
98
+ jobNeedPathRemap = false
96
99
}
100
+ } else {
101
+ jobNeedPathRemap = false
97
102
}
98
103
99
104
if let variant = parsedOptions. getLastArgument ( . targetVariant) ? . asSingle {
@@ -126,24 +131,22 @@ extension Driver {
126
131
try commandLine. appendLast ( . targetCpu, from: & parsedOptions)
127
132
128
133
if let sdkPath = frontendTargetInfo. sdkPath? . path {
129
- commandLine. appendFlag ( . sdk)
130
- commandLine. append ( . path( VirtualPath . lookup ( sdkPath) ) )
134
+ try addPathOption ( option: . sdk, path: VirtualPath . lookup ( sdkPath) , to: & commandLine, remap: jobNeedPathRemap)
131
135
}
132
136
133
137
for args : ( Option , Option ) in [
134
138
( . visualcToolsRoot, . visualcToolsVersion) ,
135
139
( . windowsSdkRoot, . windowsSdkVersion)
136
140
] {
137
- let ( rootArg, versionArg) = args
138
- if let value = parsedOptions. getLastArgument ( rootArg) ? . asSingle,
139
- isFrontendArgSupported ( rootArg) {
140
- commandLine. appendFlag ( rootArg. spelling)
141
- commandLine. appendPath ( try . init( validating: value) )
141
+ let ( rootOpt, versionOpt) = args
142
+ if let rootArg = parsedOptions. last ( for: rootOpt) ,
143
+ isFrontendArgSupported ( rootOpt) {
144
+ try addPathOption ( rootArg, to: & commandLine, remap: jobNeedPathRemap)
142
145
}
143
146
144
- if let value = parsedOptions. getLastArgument ( versionArg ) ? . asSingle,
145
- isFrontendArgSupported ( versionArg ) {
146
- commandLine. appendFlags ( versionArg . spelling, value)
147
+ if let value = parsedOptions. getLastArgument ( versionOpt ) ? . asSingle,
148
+ isFrontendArgSupported ( versionOpt ) {
149
+ commandLine. appendFlags ( versionOpt . spelling, value)
147
150
}
148
151
}
149
152
@@ -302,12 +305,14 @@ extension Driver {
302
305
commandLine. appendFlag ( . Xcc)
303
306
commandLine. appendFlag ( . workingDirectory)
304
307
commandLine. appendFlag ( . Xcc)
305
- commandLine . appendPath ( . absolute( workingDirectory) )
308
+ try addPathArgument ( . absolute( workingDirectory) , to : & commandLine , remap : jobNeedPathRemap )
306
309
}
307
310
308
311
// Resource directory.
309
- commandLine. appendFlag ( . resourceDir)
310
- commandLine. appendPath ( VirtualPath . lookup ( frontendTargetInfo. runtimeResourcePath. path) )
312
+ try addPathOption ( option: . resourceDir,
313
+ path: VirtualPath . lookup ( frontendTargetInfo. runtimeResourcePath. path) ,
314
+ to: & commandLine,
315
+ remap: jobNeedPathRemap)
311
316
312
317
if self . useStaticResourceDir {
313
318
commandLine. appendFlag ( " -use-static-resource-dir " )
@@ -347,6 +352,7 @@ extension Driver {
347
352
try commandLine. appendAll ( . casPluginOption, from: & parsedOptions)
348
353
try commandLine. appendLast ( . cacheRemarks, from: & parsedOptions)
349
354
}
355
+ addCacheReplayMapping ( to: & commandLine)
350
356
if useClangIncludeTree {
351
357
commandLine. appendFlag ( . clangIncludeTree)
352
358
}
@@ -369,16 +375,16 @@ extension Driver {
369
375
// of a lookup failure.
370
376
if parsedOptions. contains ( . pchOutputDir) &&
371
377
!parsedOptions. contains ( . driverExplicitModuleBuild) {
372
- commandLine . appendPath ( VirtualPath . lookup ( importedObjCHeader) )
378
+ try addPathArgument ( VirtualPath . lookup ( importedObjCHeader) , to : & commandLine , remap : jobNeedPathRemap )
373
379
try commandLine. appendLast ( . pchOutputDir, from: & parsedOptions)
374
380
if !compilerMode. isSingleCompilation {
375
381
commandLine. appendFlag ( . pchDisableValidation)
376
382
}
377
383
} else {
378
- commandLine . appendPath ( VirtualPath . lookup ( pch) )
384
+ try addPathArgument ( VirtualPath . lookup ( pch) , to : & commandLine , remap : jobNeedPathRemap )
379
385
}
380
386
} else {
381
- commandLine . appendPath ( VirtualPath . lookup ( importedObjCHeader) )
387
+ try addPathArgument ( VirtualPath . lookup ( importedObjCHeader) , to : & commandLine , remap : jobNeedPathRemap )
382
388
}
383
389
}
384
390
@@ -418,16 +424,17 @@ extension Driver {
418
424
}
419
425
}
420
426
421
- func addBridgingHeaderPCHCacheKeyArguments( commandLine: inout [ Job . ArgTemplate ] ,
422
- pchCompileJob: Job ? ) throws {
427
+ mutating func addBridgingHeaderPCHCacheKeyArguments( commandLine: inout [ Job . ArgTemplate ] ,
428
+ pchCompileJob: Job ? ) throws {
423
429
guard let pchJob = pchCompileJob, enableCaching else { return }
424
430
425
431
// The pch input file (the bridging header) is added as last inputs to the job.
426
432
guard let inputFile = pchJob. inputs. last else { assertionFailure ( " no input files from pch job " ) ; return }
427
433
assert ( inputFile. type == . objcHeader, " Expect objc header input type " )
434
+ let mappedInput = remapPath ( inputFile. file) . intern ( )
428
435
let bridgingHeaderCacheKey = try interModuleDependencyOracle. computeCacheKeyForOutput ( kind: . pch,
429
436
commandLine: pchJob. commandLine,
430
- input: inputFile . fileHandle )
437
+ input: mappedInput )
431
438
commandLine. appendFlag ( " -bridging-header-pch-key " )
432
439
commandLine. appendFlag ( bridgingHeaderCacheKey)
433
440
}
@@ -609,7 +616,7 @@ extension Driver {
609
616
var entries = [ VirtualPath . Handle: [ FileType: VirtualPath . Handle] ] ( )
610
617
for input in primaryInputs {
611
618
if let output = inputOutputMap [ input] ? . first {
612
- addEntry ( & entries, input: input, output: output)
619
+ try addEntry ( & entries, input: input, output: output)
613
620
} else {
614
621
// Primary inputs are expected to appear in the output file map even
615
622
// if they have no corresponding outputs.
@@ -628,7 +635,7 @@ extension Driver {
628
635
}
629
636
630
637
for flaggedPair in flaggedInputOutputPairs {
631
- addEntry ( & entries, input: flaggedPair. input, output: flaggedPair. output)
638
+ try addEntry ( & entries, input: flaggedPair. input, output: flaggedPair. output)
632
639
}
633
640
// To match the legacy driver behavior, make sure we add an entry for the
634
641
// file under indexing and the primary output file path.
@@ -662,14 +669,15 @@ extension Driver {
662
669
try commandLine. appendLast ( . symbolGraphMinimumAccessLevel, from: & parsedOptions)
663
670
}
664
671
665
- func addEntry( _ entries: inout [ VirtualPath . Handle : [ FileType : VirtualPath . Handle ] ] , input: TypedVirtualPath ? , output: TypedVirtualPath ) {
672
+ mutating func addEntry( _ entries: inout [ VirtualPath . Handle : [ FileType : VirtualPath . Handle ] ] , input: TypedVirtualPath ? , output: TypedVirtualPath ) throws {
666
673
let entryInput : VirtualPath . Handle
667
674
if let input = input? . fileHandle, input != OutputFileMap . singleInputKey {
668
675
entryInput = input
669
676
} else {
670
677
entryInput = inputFiles [ 0 ] . fileHandle
671
678
}
672
- entries [ entryInput, default: [ : ] ] [ output. type] = output. fileHandle
679
+ let inputEntry = enableCaching ? remapPath ( VirtualPath . lookup ( entryInput) ) . intern ( ) : entryInput
680
+ entries [ inputEntry, default: [ : ] ] [ output. type] = output. fileHandle
673
681
}
674
682
675
683
/// Adds all dependencies required for an explicit module build
@@ -706,3 +714,84 @@ extension Driver {
706
714
return job. moduleName == moduleOutputInfo. name
707
715
}
708
716
}
717
+
718
+ extension Driver {
719
+ private func getAbsolutePathFromVirtualPath( _ path: VirtualPath ) -> AbsolutePath ? {
720
+ guard let cwd = workingDirectory ?? fileSystem. currentWorkingDirectory else {
721
+ return nil
722
+ }
723
+ return path. resolvedRelativePath ( base: cwd) . absolutePath
724
+ }
725
+
726
+ private mutating func remapPath( absolute path: AbsolutePath ) -> AbsolutePath {
727
+ guard !prefixMapping. isEmpty else {
728
+ return path
729
+ }
730
+ for (prefix, value) in prefixMapping {
731
+ if path. isDescendantOfOrEqual ( to: prefix) {
732
+ return value. appending ( path. relative ( to: prefix) )
733
+ }
734
+ }
735
+ return path
736
+ }
737
+
738
+ public mutating func remapPath( _ path: VirtualPath ) -> VirtualPath {
739
+ guard !prefixMapping. isEmpty,
740
+ let absPath = getAbsolutePathFromVirtualPath ( path) else {
741
+ return path
742
+ }
743
+ let mappedPath = remapPath ( absolute: absPath)
744
+ return try ! VirtualPath ( path: mappedPath. pathString)
745
+ }
746
+
747
+ /// Helper function to add path to commandLine. Function will validate the path, and remap the path if needed.
748
+ public mutating func addPathArgument( _ path: VirtualPath , to commandLine: inout [ Job . ArgTemplate ] , remap: Bool = false ) throws {
749
+ guard remap && enableCaching else {
750
+ commandLine. appendPath ( path)
751
+ return
752
+ }
753
+ let mappedPath = remapPath ( path)
754
+ commandLine. appendPath ( mappedPath)
755
+ }
756
+
757
+ public mutating func addPathOption( _ option: ParsedOption , to commandLine: inout [ Job . ArgTemplate ] , remap: Bool = false ) throws {
758
+ let path = try VirtualPath ( path: option. argument. asSingle)
759
+ try addPathOption ( option: option. option, path: path, to: & commandLine, remap: remap)
760
+ }
761
+
762
+ public mutating func addPathOption( option: Option , path: VirtualPath , to commandLine: inout [ Job . ArgTemplate ] , remap: Bool = false ) throws {
763
+ commandLine. appendFlag ( option)
764
+ let needRemap = remap && option. attributes. contains ( . argumentIsPath) &&
765
+ !option. attributes. contains ( . cacheInvariant)
766
+ try addPathArgument ( path, to: & commandLine, remap: needRemap)
767
+
768
+ }
769
+
770
+ /// Helper function to add last argument with path to command-line.
771
+ public mutating func addLastArgumentWithPath( _ options: Option ... ,
772
+ from parsedOptions: inout ParsedOptions ,
773
+ to commandLine: inout [ Job . ArgTemplate ] ) throws {
774
+ guard let parsedOption = parsedOptions. last ( for: options) else {
775
+ return
776
+ }
777
+ try addPathOption ( parsedOption, to: & commandLine)
778
+ }
779
+
780
+ /// Helper function to add all arguments with path to command-line.
781
+ public mutating func addAllArgumentsWithPath( _ options: Option ... ,
782
+ from parsedOptions: inout ParsedOptions ,
783
+ to commandLine: inout [ Job . ArgTemplate ] ) throws {
784
+ for matching in parsedOptions. arguments ( for: options) {
785
+ try addPathOption ( matching, to: & commandLine)
786
+ }
787
+ }
788
+
789
+ public mutating func addCacheReplayMapping( to commandLine: inout [ Job . ArgTemplate ] ) {
790
+ if enableCaching && isFrontendArgSupported ( . scannerPrefixMap) {
791
+ for (key, value) in prefixMapping {
792
+ commandLine. appendFlag ( " -cache-replay-prefix-map " )
793
+ commandLine. appendFlag ( value. pathString + " = " + key. pathString)
794
+ }
795
+ }
796
+ }
797
+ }
0 commit comments