@@ -13,6 +13,12 @@ import Foundation
13
13
import TSCBasic
14
14
import SwiftOptions
15
15
16
+ extension Diagnostic . Message {
17
+ static func warn_scanner_frontend_fallback( ) -> Diagnostic . Message {
18
+ . warning( " Fallback to `swift-frontend` dependency scanner invocation " )
19
+ }
20
+ }
21
+
16
22
internal extension Driver {
17
23
/// Precompute the dependencies for a given Swift compilation, producing a
18
24
/// dependency graph including all Swift and C module files and
@@ -39,7 +45,7 @@ internal extension Driver {
39
45
// Aggregate the fast dependency scanner arguments
40
46
var inputs : [ TypedVirtualPath ] = [ ]
41
47
var commandLine : [ Job . ArgTemplate ] = swiftCompilerPrefixArgs. map { Job . ArgTemplate. flag ( $0) }
42
-
48
+ commandLine . appendFlag ( " -frontend " )
43
49
commandLine. appendFlag ( " -scan-dependencies " )
44
50
try addCommonFrontendOptions ( commandLine: & commandLine, inputs: & inputs,
45
51
bridgingHeaderHandling: . precompiled,
@@ -93,24 +99,36 @@ internal extension Driver {
93
99
let forceResponseFiles = parsedOptions. hasArgument ( . driverForceResponseFiles)
94
100
let dependencyGraph : InterModuleDependencyGraph
95
101
96
- if ( !parsedOptions. hasArgument ( . driverScanDependenciesNonLib) ) {
97
- try interModuleDependencyOracle
102
+ // If `-nonlib-dependency-scanner` was specified or the libSwiftScan library cannot be found,
103
+ // attempt to fallback to using `swift-frontend -scan-dependencies` invocations for dependency
104
+ // scanning.
105
+ var fallbackToFrontend = parsedOptions. hasArgument ( . driverScanDependenciesNonLib)
106
+ if try interModuleDependencyOracle
98
107
. verifyOrCreateScannerInstance ( fileSystem: fileSystem,
99
- swiftScanLibPath: try getScanLibPath ( of: toolchain) )
108
+ swiftScanLibPath: try getScanLibPath ( of: toolchain) ) == false {
109
+ fallbackToFrontend = true
110
+ diagnosticEngine. emit ( . warn_scanner_frontend_fallback( ) )
111
+ }
112
+
113
+ if ( !fallbackToFrontend) {
100
114
let cwd = workingDirectory ?? fileSystem. currentWorkingDirectory!
101
115
var command = try itemizedJobCommand ( of: scannerJob,
102
116
forceResponseFiles: forceResponseFiles,
103
117
using: executor. resolver)
104
118
// Remove the tool executable to only leave the arguments
105
119
command. removeFirst ( )
120
+ // We generate full swiftc -frontend -scan-dependencies invocations in order to also be
121
+ // able to launch them as standalone jobs. Frontend's argument parser won't recognize
122
+ // -frontend when passed directly.
123
+ if command. first == " -frontend " {
124
+ command. removeFirst ( )
125
+ }
106
126
dependencyGraph =
107
127
try interModuleDependencyOracle. getDependencies ( workingDirectory: cwd,
108
128
commandLine: command)
109
129
} else {
110
130
// Fallback to legacy invocation of the dependency scanner with
111
131
// `swift-frontend -scan-dependencies`
112
- print ( " Dependency Scanner invocation: " )
113
- print ( try executor. description ( of: scannerJob, forceResponseFiles: false ) )
114
132
dependencyGraph =
115
133
try self . executor. execute ( job: scannerJob,
116
134
capturingJSONOutputAs: InterModuleDependencyGraph . self,
@@ -125,26 +143,38 @@ internal extension Driver {
125
143
let batchScanningJob = try batchDependencyScanningJob ( for: moduleInfos)
126
144
let forceResponseFiles = parsedOptions. hasArgument ( . driverForceResponseFiles)
127
145
128
- let moduleVersionedGraphMap : [ ModuleDependencyId : [ InterModuleDependencyGraph ] ]
129
- if ( !parsedOptions. hasArgument ( . driverScanDependenciesNonLib) ) {
130
- try interModuleDependencyOracle
146
+ // If `-nonlib-dependency-scanner` was specified or the libSwiftScan library cannot be found,
147
+ // attempt to fallback to using `swift-frontend -scan-dependencies` invocations for dependency
148
+ // scanning.
149
+ var fallbackToFrontend = parsedOptions. hasArgument ( . driverScanDependenciesNonLib)
150
+ if try interModuleDependencyOracle
131
151
. verifyOrCreateScannerInstance ( fileSystem: fileSystem,
132
- swiftScanLibPath: try getScanLibPath ( of: toolchain) )
152
+ swiftScanLibPath: try getScanLibPath ( of: toolchain) ) == false {
153
+ fallbackToFrontend = true
154
+ diagnosticEngine. emit ( . warn_scanner_frontend_fallback( ) )
155
+ }
156
+
157
+ let moduleVersionedGraphMap : [ ModuleDependencyId : [ InterModuleDependencyGraph ] ]
158
+ if ( !fallbackToFrontend) {
133
159
let cwd = workingDirectory ?? fileSystem. currentWorkingDirectory!
134
160
var command = try itemizedJobCommand ( of: batchScanningJob,
135
161
forceResponseFiles: forceResponseFiles,
136
162
using: executor. resolver)
137
163
// Remove the tool executable to only leave the arguments
138
164
command. removeFirst ( )
165
+ // We generate full swiftc -frontend -scan-dependencies invocations in order to also be
166
+ // able to launch them as standalone jobs. Frontend's argument parser won't recognize
167
+ // -frontend when passed directly.
168
+ if command. first == " -frontend " {
169
+ command. removeFirst ( )
170
+ }
139
171
moduleVersionedGraphMap =
140
172
try interModuleDependencyOracle. getBatchDependencies ( workingDirectory: cwd,
141
173
commandLine: command,
142
174
batchInfos: moduleInfos)
143
175
} else {
144
176
// Fallback to legacy invocation of the dependency scanner with
145
177
// `swift-frontend -scan-dependencies`
146
- print ( " Dependency Scanner (batch) invocation: " )
147
- print ( try executor. description ( of: batchScanningJob, forceResponseFiles: false ) )
148
178
moduleVersionedGraphMap = try executeLegacyBatchScan ( moduleInfos: moduleInfos,
149
179
batchScanningJob: batchScanningJob,
150
180
forceResponseFiles: forceResponseFiles)
@@ -203,6 +233,7 @@ internal extension Driver {
203
233
204
234
// The dependency scanner automatically operates in batch mode if -batch-scan-input-file
205
235
// is present.
236
+ commandLine. appendFlag ( " -frontend " )
206
237
commandLine. appendFlag ( " -scan-dependencies " )
207
238
try addCommonFrontendOptions ( commandLine: & commandLine, inputs: & inputs,
208
239
bridgingHeaderHandling: . precompiled,
0 commit comments