Skip to content

Commit 92bdabe

Browse files
committed
Revert "Allow for non-external lookup of libSwiftScan symbols and centralize …"
This reverts commit d616136.
1 parent 91beadc commit 92bdabe

File tree

15 files changed

+333
-412
lines changed

15 files changed

+333
-412
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 44 additions & 165 deletions
Large diffs are not rendered by default.

Sources/SwiftDriver/Execution/DriverExecutor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public struct DriverExecutorWorkload {
8080
}
8181
}
8282

83-
@_spi(Testing) public enum JobExecutionError: Error {
83+
enum JobExecutionError: Error {
8484
case jobFailedWithNonzeroExitCode(Int, String)
8585
case failedToReadJobOutput
8686
// A way to pass more information to the catch point

Sources/SwiftDriver/ExplicitModuleBuilds/InterModuleDependencies/InterModuleDependencyOracle.swift

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,16 @@ public class InterModuleDependencyOracle {
8383
}
8484

8585
/// Given a specified toolchain path, locate and instantiate an instance of the SwiftScan library
86-
public func verifyOrCreateScannerInstance(swiftScanLibPath: AbsolutePath?) throws {
86+
public func verifyOrCreateScannerInstance(fileSystem: FileSystem,
87+
swiftScanLibPath: AbsolutePath) throws {
8788
return try queue.sync {
88-
guard let scanInstance = swiftScanLibInstance else {
89+
if swiftScanLibInstance == nil {
8990
swiftScanLibInstance = try SwiftScan(dylib: swiftScanLibPath)
90-
return
91-
}
92-
93-
guard scanInstance.path?.description == swiftScanLibPath?.description else {
94-
throw DependencyScanningError
95-
.scanningLibraryInvocationMismatch(scanInstance.path?.description ?? "built-in",
96-
swiftScanLibPath?.description ?? "built-in")
91+
} else {
92+
guard swiftScanLibInstance!.path == swiftScanLibPath else {
93+
throw DependencyScanningError
94+
.scanningLibraryInvocationMismatch(swiftScanLibInstance!.path, swiftScanLibPath)
95+
}
9796
}
9897
}
9998
}
@@ -210,20 +209,10 @@ public class InterModuleDependencyOracle {
210209
}
211210
}
212211

213-
// Note: this is `true` even in the `compilerIntegratedTooling` mode
214-
// where the `SwiftScan` instance refers to the own image the driver is
215-
// running in, since there is still technically a `SwiftScan` handle
216-
// capable of handling API requests expected of it.
217212
private var hasScannerInstance: Bool { self.swiftScanLibInstance != nil }
218-
func getScannerInstance() -> SwiftScan? {
219-
self.swiftScanLibInstance
220-
}
221-
func setScannerInstance(_ instance: SwiftScan?) {
222-
self.swiftScanLibInstance = instance
223-
}
224213

225214
/// Queue to sunchronize accesses to the scanner
226-
let queue = DispatchQueue(label: "org.swift.swift-driver.swift-scan")
215+
internal let queue = DispatchQueue(label: "org.swift.swift-driver.swift-scan")
227216

228217
/// A reference to an instance of the compiler's libSwiftScan shared library
229218
private var swiftScanLibInstance: SwiftScan? = nil

Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,41 @@ public extension Driver {
164164
contents)
165165
}
166166

167+
/// Returns false if the lib is available and ready to use
168+
private mutating func initSwiftScanLib() throws -> Bool {
169+
// `-nonlib-dependency-scanner` was specified
170+
guard !parsedOptions.hasArgument(.driverScanDependenciesNonLib) else {
171+
return true
172+
}
173+
174+
// If the libSwiftScan library cannot be found,
175+
// attempt to fallback to using `swift-frontend -scan-dependencies` invocations for dependency
176+
// scanning.
177+
guard let scanLibPath = try toolchain.lookupSwiftScanLib(),
178+
fileSystem.exists(scanLibPath) else {
179+
diagnosticEngine.emit(.warn_scan_dylib_not_found())
180+
return true
181+
}
182+
183+
do {
184+
try interModuleDependencyOracle.verifyOrCreateScannerInstance(fileSystem: fileSystem,
185+
swiftScanLibPath: scanLibPath)
186+
if isCachingEnabled {
187+
self.cas = try interModuleDependencyOracle.getOrCreateCAS(pluginPath: try getCASPluginPath(),
188+
onDiskPath: try getOnDiskCASPath(),
189+
pluginOptions: try getCASPluginOptions())
190+
}
191+
} catch {
192+
if isCachingEnabled {
193+
diagnosticEngine.emit(.error_caching_enabled_libswiftscan_load_failure(scanLibPath.description))
194+
} else {
195+
diagnosticEngine.emit(.warn_scan_dylib_load_failed(scanLibPath.description))
196+
}
197+
return true
198+
}
199+
return false
200+
}
201+
167202
static func sanitizeCommandForLibScanInvocation(_ command: inout [String]) {
168203
// Remove the tool executable to only leave the arguments. When passing the
169204
// command line into libSwiftScan, the library is itself the tool and only
@@ -182,7 +217,8 @@ public extension Driver {
182217
let forceResponseFiles = parsedOptions.hasArgument(.driverForceResponseFiles)
183218
let imports: InterModuleDependencyImports
184219

185-
if supportInProcessSwiftScanQueries {
220+
let isSwiftScanLibAvailable = !(try initSwiftScanLib())
221+
if isSwiftScanLibAvailable {
186222
var scanDiagnostics: [ScannerDiagnosticPayload] = []
187223
guard let cwd = workingDirectory else {
188224
throw DependencyScanningError.dependencyScanFailed("cannot determine working directory")
@@ -258,7 +294,8 @@ public extension Driver {
258294
stdoutStream.flush()
259295
}
260296

261-
if supportInProcessSwiftScanQueries {
297+
let isSwiftScanLibAvailable = !(try initSwiftScanLib())
298+
if isSwiftScanLibAvailable {
262299
var scanDiagnostics: [ScannerDiagnosticPayload] = []
263300
guard let cwd = workingDirectory else {
264301
throw DependencyScanningError.dependencyScanFailed("cannot determine working directory")
@@ -296,7 +333,8 @@ public extension Driver {
296333
let forceResponseFiles = parsedOptions.hasArgument(.driverForceResponseFiles)
297334
let moduleVersionedGraphMap: [ModuleDependencyId: [InterModuleDependencyGraph]]
298335

299-
if supportInProcessSwiftScanQueries {
336+
let isSwiftScanLibAvailable = !(try initSwiftScanLib())
337+
if isSwiftScanLibAvailable {
300338
var scanDiagnostics: [ScannerDiagnosticPayload] = []
301339
guard let cwd = workingDirectory else {
302340
throw DependencyScanningError.dependencyScanFailed("cannot determine working directory")
@@ -464,7 +502,3 @@ public extension Driver {
464502
.parentDirectory // toolchain root
465503
}
466504
}
467-
468-
extension Driver {
469-
var supportInProcessSwiftScanQueries: Bool { return self.swiftScanLibInstance != nil }
470-
}

Sources/SwiftDriver/Jobs/EmitSupportedFeaturesJob.swift

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,18 @@ extension Toolchain {
5959
extension Driver {
6060

6161
static func computeSupportedCompilerArgs(of toolchain: Toolchain,
62-
libSwiftScan: SwiftScan?,
6362
parsedOptions: inout ParsedOptions,
6463
diagnosticsEngine: DiagnosticsEngine,
6564
fileSystem: FileSystem,
6665
executor: DriverExecutor)
6766
throws -> Set<String> {
68-
if let libSwiftScanInstance = libSwiftScan,
69-
libSwiftScanInstance.canQuerySupportedArguments() {
70-
do {
71-
return try libSwiftScanInstance.querySupportedArguments()
72-
} catch {
73-
diagnosticsEngine.emit(.remark_inprocess_supported_features_query_failed(error.localizedDescription))
67+
do {
68+
if let supportedArgs =
69+
try querySupportedCompilerArgsInProcess(of: toolchain, fileSystem: fileSystem) {
70+
return supportedArgs
7471
}
72+
} catch {
73+
diagnosticsEngine.emit(.remark_inprocess_supported_features_query_failed(error.localizedDescription))
7574
}
7675

7776
// Fallback: Invoke `swift-frontend -emit-supported-features` and decode the output
@@ -89,6 +88,20 @@ extension Driver {
8988
return Set(decodedSupportedFlagList)
9089
}
9190

91+
static func querySupportedCompilerArgsInProcess(of toolchain: Toolchain,
92+
fileSystem: FileSystem)
93+
throws -> Set<String>? {
94+
let optionalSwiftScanLibPath = try toolchain.lookupSwiftScanLib()
95+
if let swiftScanLibPath = optionalSwiftScanLibPath,
96+
fileSystem.exists(swiftScanLibPath) {
97+
let libSwiftScanInstance = try SwiftScan(dylib: swiftScanLibPath)
98+
if libSwiftScanInstance.canQuerySupportedArguments() {
99+
return try libSwiftScanInstance.querySupportedArguments()
100+
}
101+
}
102+
return nil
103+
}
104+
92105
static func computeSupportedCompilerFeatures(of toolchain: Toolchain,
93106
env: [String: String]) throws -> Set<String> {
94107
struct FeatureInfo: Codable {

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -406,13 +406,11 @@ extension Driver {
406406
// CAS related options.
407407
if isCachingEnabled {
408408
commandLine.appendFlag(.cacheCompileJob)
409-
if let casPath = try Self.getOnDiskCASPath(parsedOptions: &parsedOptions,
410-
toolchain: toolchain) {
409+
if let casPath = try getOnDiskCASPath() {
411410
commandLine.appendFlag(.casPath)
412411
commandLine.appendFlag(casPath.pathString)
413412
}
414-
if let pluginPath = try Self.getCASPluginPath(parsedOptions: &parsedOptions,
415-
toolchain: toolchain) {
413+
if let pluginPath = try getCASPluginPath() {
416414
commandLine.appendFlag(.casPluginPath)
417415
commandLine.appendFlag(pluginPath.pathString)
418416
}

Sources/SwiftDriver/Jobs/PrintTargetInfoJob.swift

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -181,39 +181,46 @@ extension Toolchain {
181181
}
182182

183183
extension Driver {
184-
@_spi(Testing) public static func queryTargetInfoInProcess(libSwiftScanInstance: SwiftScan,
185-
toolchain: Toolchain,
184+
@_spi(Testing) public static func queryTargetInfoInProcess(of toolchain: Toolchain,
186185
fileSystem: FileSystem,
187186
workingDirectory: AbsolutePath?,
188-
invocationCommand: [String]) throws -> FrontendTargetInfo {
189-
let cwd = try workingDirectory ?? fileSystem.tempDirectory
190-
let compilerExecutablePath = try toolchain.resolvedTool(.swiftCompiler).path
191-
let targetInfoData =
192-
try libSwiftScanInstance.queryTargetInfoJSON(workingDirectory: cwd,
193-
compilerExecutablePath: compilerExecutablePath,
194-
invocationCommand: invocationCommand)
195-
do {
196-
return try JSONDecoder().decode(FrontendTargetInfo.self, from: targetInfoData)
197-
} catch let decodingError as DecodingError {
198-
let stringToDecode = String(data: targetInfoData, encoding: .utf8)
199-
let errorDesc: String
200-
switch decodingError {
201-
case let .typeMismatch(type, context):
202-
errorDesc = "type mismatch: \(type), path: \(context.codingPath)"
203-
case let .valueNotFound(type, context):
204-
errorDesc = "value missing: \(type), path: \(context.codingPath)"
205-
case let .keyNotFound(key, context):
206-
errorDesc = "key missing: \(key), path: \(context.codingPath)"
207-
case let .dataCorrupted(context):
208-
errorDesc = "data corrupted at path: \(context.codingPath)"
209-
@unknown default:
210-
errorDesc = "unknown decoding error"
187+
invocationCommand: [String]) throws -> FrontendTargetInfo? {
188+
let optionalSwiftScanLibPath = try toolchain.lookupSwiftScanLib()
189+
if let swiftScanLibPath = optionalSwiftScanLibPath,
190+
fileSystem.exists(swiftScanLibPath) {
191+
let libSwiftScanInstance = try SwiftScan(dylib: swiftScanLibPath)
192+
if libSwiftScanInstance.canQueryTargetInfo() {
193+
let cwd = try workingDirectory ?? fileSystem.tempDirectory
194+
let compilerExecutablePath = try toolchain.resolvedTool(.swiftCompiler).path
195+
let targetInfoData =
196+
try libSwiftScanInstance.queryTargetInfoJSON(workingDirectory: cwd,
197+
compilerExecutablePath: compilerExecutablePath,
198+
invocationCommand: invocationCommand)
199+
do {
200+
return try JSONDecoder().decode(FrontendTargetInfo.self, from: targetInfoData)
201+
} catch let decodingError as DecodingError {
202+
let stringToDecode = String(data: targetInfoData, encoding: .utf8)
203+
let errorDesc: String
204+
switch decodingError {
205+
case let .typeMismatch(type, context):
206+
errorDesc = "type mismatch: \(type), path: \(context.codingPath)"
207+
case let .valueNotFound(type, context):
208+
errorDesc = "value missing: \(type), path: \(context.codingPath)"
209+
case let .keyNotFound(key, context):
210+
errorDesc = "key missing: \(key), path: \(context.codingPath)"
211+
case let .dataCorrupted(context):
212+
errorDesc = "data corrupted at path: \(context.codingPath)"
213+
@unknown default:
214+
errorDesc = "unknown decoding error"
215+
}
216+
throw Error.unableToDecodeFrontendTargetInfo(
217+
stringToDecode,
218+
invocationCommand,
219+
errorDesc)
220+
}
211221
}
212-
throw Error.unableToDecodeFrontendTargetInfo(
213-
stringToDecode,
214-
invocationCommand,
215-
errorDesc)
216222
}
223+
return nil
217224
}
218225

219226
static func computeTargetInfo(target: Triple?,
@@ -224,7 +231,6 @@ extension Driver {
224231
requiresInPlaceExecution: Bool = false,
225232
useStaticResourceDir: Bool = false,
226233
swiftCompilerPrefixArgs: [String],
227-
libSwiftScan: SwiftScan?,
228234
toolchain: Toolchain,
229235
fileSystem: FileSystem,
230236
workingDirectory: AbsolutePath?,
@@ -237,19 +243,20 @@ extension Driver {
237243
requiresInPlaceExecution: requiresInPlaceExecution,
238244
useStaticResourceDir: useStaticResourceDir,
239245
swiftCompilerPrefixArgs: swiftCompilerPrefixArgs)
240-
if let libSwiftScanInstance = libSwiftScan,
241-
libSwiftScanInstance.canQueryTargetInfo() {
242-
do {
243-
var command = try Self.itemizedJobCommand(of: frontendTargetInfoJob,
244-
useResponseFiles: .disabled,
245-
using: executor.resolver)
246-
Self.sanitizeCommandForLibScanInvocation(&command)
247-
return try Self.queryTargetInfoInProcess(libSwiftScanInstance: libSwiftScanInstance, toolchain: toolchain,
248-
fileSystem: fileSystem, workingDirectory: workingDirectory,
249-
invocationCommand: command)
250-
} catch {
251-
diagnosticsEngine.emit(.remark_inprocess_target_info_query_failed(error.localizedDescription))
246+
var command = try Self.itemizedJobCommand(of: frontendTargetInfoJob,
247+
useResponseFiles: .disabled,
248+
using: executor.resolver)
249+
Self.sanitizeCommandForLibScanInvocation(&command)
250+
251+
do {
252+
if let targetInfo =
253+
try Self.queryTargetInfoInProcess(of: toolchain, fileSystem: fileSystem,
254+
workingDirectory: workingDirectory,
255+
invocationCommand: command) {
256+
return targetInfo
252257
}
258+
} catch {
259+
diagnosticsEngine.emit(.remark_inprocess_target_info_query_failed(error.localizedDescription))
253260
}
254261

255262
// Fallback: Invoke `swift-frontend -print-target-info` and decode the output

Sources/SwiftDriver/SwiftScan/Loader.swift

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -161,19 +161,6 @@ extension Loader {
161161
return Handle(value: handle)
162162
}
163163

164-
public static func getSelfHandle(mode: Flags) throws -> Handle {
165-
#if os(Windows)
166-
guard let handle = GetModuleHandleW(nil) else {
167-
throw Loader.Error.open("GetModuleHandleW(nil) failure: \(GetLastError())")
168-
}
169-
#else
170-
guard let handle = dlopen(nil, mode.rawValue) else {
171-
throw Loader.Error.open(Loader.error() ?? "unknown error")
172-
}
173-
#endif
174-
return Handle(value: handle)
175-
}
176-
177164
public static func lookup<T>(symbol: String, in module: Handle) -> T? {
178165
#if os(Windows)
179166
guard let pointer = GetProcAddress(module.value!, symbol) else {

0 commit comments

Comments
 (0)