@@ -24,6 +24,9 @@ extension Driver {
24
24
var commandLine : [ Job . ArgTemplate ] = swiftCompilerPrefixArgs. map { Job . ArgTemplate. flag ( $0) }
25
25
commandLine. appendFlag ( " -frontend " )
26
26
commandLine. appendFlag ( " -scan-dependencies " )
27
+ if parsedOptions. hasArgument ( . parseStdlib) {
28
+ commandLine. appendFlag ( . disableObjcAttrRequiresFoundationModule)
29
+ }
27
30
try addCommonFrontendOptions ( commandLine: & commandLine, inputs: & inputs,
28
31
bridgingHeaderHandling: . precompiled,
29
32
moduleDependencyGraphUse: . dependencyScan)
@@ -72,105 +75,65 @@ extension Driver {
72
75
return placeholderMapFilePath
73
76
}
74
77
75
- mutating func performBatchDependencyScan( moduleInfos: [ BatchScanModuleInfo ] )
76
- throws -> [ ModuleDependencyId : [ InterModuleDependencyGraph ] ] {
77
- let batchScanningJob = try batchDependencyScanningJob ( for: moduleInfos)
78
- let forceResponseFiles = parsedOptions. hasArgument ( . driverForceResponseFiles)
79
- let batchScanResult =
80
- try self . executor. execute ( job: batchScanningJob,
81
- forceResponseFiles: forceResponseFiles,
82
- recordedInputModificationDates: recordedInputModificationDates)
83
- let success = batchScanResult. exitStatus == . terminated( code: EXIT_SUCCESS)
84
- guard success else {
85
- throw JobExecutionError . jobFailedWithNonzeroExitCode (
86
- SwiftDriverExecutor . computeReturnCode ( exitStatus: batchScanResult. exitStatus) ,
87
- try batchScanResult. utf8stderrOutput ( ) )
88
- }
89
-
90
- // Decode the resulting dependency graphs and build a dictionary from a moduleId to
91
- // a set of dependency graphs that were built for it
92
- let moduleVersionedGraphMap =
93
- try moduleInfos. reduce ( into: [ ModuleDependencyId: [ InterModuleDependencyGraph] ] ( ) ) {
94
- let moduleId : ModuleDependencyId
95
- let dependencyGraphPath : VirtualPath
96
- switch $1 {
97
- case . swift( let swiftModuleBatchScanInfo) :
98
- moduleId = . swift( swiftModuleBatchScanInfo. swiftModuleName)
99
- dependencyGraphPath = try VirtualPath ( path: swiftModuleBatchScanInfo. output)
100
- case . clang( let clangModuleBatchScanInfo) :
101
- moduleId = . clang( clangModuleBatchScanInfo. clangModuleName)
102
- dependencyGraphPath = try VirtualPath ( path: clangModuleBatchScanInfo. output)
103
- }
104
- let contents = try fileSystem. readFileContents ( dependencyGraphPath)
105
- let decodedGraph = try JSONDecoder ( ) . decode ( InterModuleDependencyGraph . self,
106
- from: Data ( contents. contents) )
107
- if $0 [ moduleId] != nil {
108
- $0 [ moduleId] !. append ( decodedGraph)
109
- } else {
110
- $0 [ moduleId] = [ decodedGraph]
111
- }
112
- }
113
- return moduleVersionedGraphMap
114
- }
115
-
116
- /// Precompute the dependencies for a given collection of modules using swift frontend's batch scanning mode
117
- mutating func batchDependencyScanningJob( for moduleInfos: [ BatchScanModuleInfo ] ) throws -> Job {
78
+ /// Compute the dependencies for a given Clang module, by invoking the Clang dependency scanning action
79
+ /// with the given module's name and a set of arguments (including the target version)
80
+ mutating func clangDependencyScanningJob( moduleId: ModuleDependencyId ,
81
+ pcmArgs: [ String ] ) throws -> Job {
118
82
var inputs : [ TypedVirtualPath ] = [ ]
119
83
120
84
// Aggregate the fast dependency scanner arguments
121
85
var commandLine : [ Job . ArgTemplate ] = swiftCompilerPrefixArgs. map { Job . ArgTemplate. flag ( $0) }
122
86
commandLine. appendFlag ( " -frontend " )
123
- // The dependency scanner automatically operates in batch mode if -batch-scan-input-file
124
- // is present.
125
- commandLine. appendFlag ( " -scan-dependencies " )
87
+ commandLine. appendFlag ( " -scan-clang-dependencies " )
88
+
126
89
try addCommonFrontendOptions ( commandLine: & commandLine, inputs: & inputs,
127
90
bridgingHeaderHandling: . precompiled,
128
91
moduleDependencyGraphUse: . dependencyScan)
129
92
130
- let batchScanInputFilePath = try serializeBatchScanningModuleArtifacts ( moduleInfos: moduleInfos)
131
- commandLine. appendFlag ( " -batch-scan-input-file " )
132
- commandLine. appendPath ( batchScanInputFilePath)
93
+ // Ensure the `-target` option is inherited from the dependent Swift module's PCM args
94
+ if let targetOptionIndex = pcmArgs. firstIndex ( of: Option . target. spelling) {
95
+ // PCM args are formulated as Clang command line options specified with:
96
+ // -Xcc <option> -Xcc <option_value>
97
+ assert ( pcmArgs. count > targetOptionIndex + 1 && pcmArgs [ targetOptionIndex + 1 ] == " -Xcc " )
98
+ let pcmArgTriple = Triple ( pcmArgs [ targetOptionIndex + 2 ] )
99
+ // Override the invocation's default target argument by appending the one extracted from
100
+ // the pcmArgs
101
+ commandLine. appendFlag ( . target)
102
+ commandLine. appendFlag ( pcmArgTriple. triple)
103
+ }
104
+
105
+ // Add the PCM args specific to this scan
106
+ pcmArgs. forEach { commandLine. appendFlags ( $0) }
133
107
134
108
// This action does not require any input files, but all frontend actions require
135
109
// at least one input so pick any input of the current compilation.
136
110
let inputFile = inputFiles. first { $0. type == . swift }
137
111
commandLine. appendPath ( inputFile!. file)
138
112
inputs. append ( inputFile!)
139
113
140
- // This job's outputs are defined as a set of dependency graph json files
141
- let outputs : [ TypedVirtualPath ] = try moduleInfos. map {
142
- switch $0 {
143
- case . swift( let swiftModuleBatchScanInfo) :
144
- return TypedVirtualPath ( file: try VirtualPath ( path: swiftModuleBatchScanInfo. output) ,
145
- type: . jsonDependencies)
146
- case . clang( let clangModuleBatchScanInfo) :
147
- return TypedVirtualPath ( file: try VirtualPath ( path: clangModuleBatchScanInfo. output) ,
148
- type: . jsonDependencies)
149
- }
150
- }
151
-
114
+ commandLine. appendFlags ( " -module-name " , moduleId. moduleName)
152
115
// Construct the scanning job.
153
116
return Job ( moduleName: moduleOutputInfo. name,
154
- kind: . scanDependencies ,
117
+ kind: . scanClangDependencies ,
155
118
tool: VirtualPath . absolute ( try toolchain. getToolPath ( . swiftCompiler) ) ,
156
119
commandLine: commandLine,
157
120
displayInputs: inputs,
158
121
inputs: inputs,
159
- outputs: outputs ,
122
+ outputs: [ TypedVirtualPath ( file : . standardOutput , type : . jsonDependencies ) ] ,
160
123
supportsResponseFiles: true )
161
124
}
162
125
163
- /// Serialize a collection of modules into an input format expected by the batch module dependency scanner.
164
- func serializeBatchScanningModuleArtifacts( moduleInfos: [ BatchScanModuleInfo ] )
165
- throws -> AbsolutePath {
166
- let temporaryDirectory = try determineTempDirectory ( )
167
- let batchScanInputFilePath =
168
- temporaryDirectory. appending ( component: " \( moduleOutputInfo. name) -batch-module-scan.json " )
126
+ mutating func scanClangModule( moduleId: ModuleDependencyId , pcmArgs: [ String ] )
127
+ throws -> InterModuleDependencyGraph {
128
+ let clangDependencyScannerJob = try clangDependencyScanningJob ( moduleId: moduleId,
129
+ pcmArgs: pcmArgs)
130
+ let forceResponseFiles = parsedOptions. hasArgument ( . driverForceResponseFiles)
169
131
170
- let encoder = JSONEncoder ( )
171
- encoder. outputFormatting = [ . prettyPrinted]
172
- let contents = try encoder. encode ( moduleInfos)
173
- try fileSystem. writeFileContents ( batchScanInputFilePath, bytes: ByteString ( contents) )
174
- return batchScanInputFilePath
132
+ let dependencyGraph =
133
+ try self . executor. execute ( job: clangDependencyScannerJob,
134
+ capturingJSONOutputAs: InterModuleDependencyGraph . self,
135
+ forceResponseFiles: forceResponseFiles,
136
+ recordedInputModificationDates: recordedInputModificationDates)
137
+ return dependencyGraph
175
138
}
176
139
}
0 commit comments