Skip to content

Commit d5d64d1

Browse files
[SwiftScan] Add APIs to load/check libSwiftScan directly
Add APIs for SwiftDriver library users to directly load/check the libSwiftScan directly before calling into its function. * Add APIs to query Driver for libSwiftScan location * Make `verifyOrCreateScannerInstance` to be public APIs to load or check the libSwiftScan. * Update `verifyOrCreateScannerInstance` to be more ergonomic to use. The function only returns true if the given path to libSwiftScan does not exist while most of the time caller actually errors out in those cases. Make throwing error the default behavior and caller can check for file existance before calling the function to perserve old behavior.
1 parent 9dd3191 commit d5d64d1

File tree

6 files changed

+50
-103
lines changed

6 files changed

+50
-103
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,10 @@ public struct Driver {
487487
return supportedFrontendFeatures.contains(feature.rawValue)
488488
}
489489

490+
public func getSwiftScanLibPath() throws -> AbsolutePath? {
491+
return try toolchain.lookupSwiftScanLib()
492+
}
493+
490494
@_spi(Testing)
491495
public static func findBlocklists(RelativeTo execDir: AbsolutePath) throws -> [AbsolutePath] {
492496
// Expect to find all blocklists in such dir:

Sources/SwiftDriver/ExplicitModuleBuilds/InterModuleDependencies/InterModuleDependencyOracle.swift

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,23 +77,17 @@ public class InterModuleDependencyOracle {
7777
}
7878

7979
/// Given a specified toolchain path, locate and instantiate an instance of the SwiftScan library
80-
/// Returns True if a library instance exists (either verified or newly-created).
81-
@_spi(Testing) public func verifyOrCreateScannerInstance(fileSystem: FileSystem,
82-
swiftScanLibPath: AbsolutePath)
83-
throws -> Bool {
80+
public func verifyOrCreateScannerInstance(fileSystem: FileSystem,
81+
swiftScanLibPath: AbsolutePath) throws {
8482
return try queue.sync {
8583
if swiftScanLibInstance == nil {
86-
guard fileSystem.exists(swiftScanLibPath) else {
87-
return false
88-
}
8984
swiftScanLibInstance = try SwiftScan(dylib: swiftScanLibPath)
9085
} else {
9186
guard swiftScanLibInstance!.path == swiftScanLibPath else {
9287
throw DependencyScanningError
9388
.scanningLibraryInvocationMismatch(swiftScanLibInstance!.path, swiftScanLibPath)
9489
}
9590
}
96-
return true
9791
}
9892
}
9993

Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -159,25 +159,26 @@ public extension Driver {
159159
// If `-nonlib-dependency-scanner` was specified or the libSwiftScan library cannot be found,
160160
// attempt to fallback to using `swift-frontend -scan-dependencies` invocations for dependency
161161
// scanning.
162-
var fallbackToFrontend = parsedOptions.hasArgument(.driverScanDependenciesNonLib)
163-
let optionalScanLibPath = try toolchain.lookupSwiftScanLib()
164-
if let scanLibPath = optionalScanLibPath,
165-
try interModuleDependencyOracle
166-
.verifyOrCreateScannerInstance(fileSystem: fileSystem,
167-
swiftScanLibPath: scanLibPath) == false {
168-
fallbackToFrontend = true
162+
guard !parsedOptions.hasArgument(.driverScanDependenciesNonLib),
163+
let scanLibPath = try toolchain.lookupSwiftScanLib(),
164+
fileSystem.exists(scanLibPath) else {
169165
// This warning is mostly useful for debugging the driver, so let's hide it
170-
// when libSwiftDriver is used, instead of a swift-driver executable.
166+
// when libSwiftDriver is used, instead of a swift-driver executable.
171167
if !integratedDriver {
172168
diagnosticEngine.emit(.warn_scanner_frontend_fallback())
173169
}
170+
171+
return true
174172
}
175-
if !fallbackToFrontend && isCachingEnabled {
173+
174+
try interModuleDependencyOracle.verifyOrCreateScannerInstance(fileSystem: fileSystem,
175+
swiftScanLibPath: scanLibPath)
176+
if isCachingEnabled {
176177
self.cas = try interModuleDependencyOracle.getOrCreateCAS(pluginPath: try getCASPluginPath(),
177178
onDiskPath: try getOnDiskCASPath(),
178179
pluginOptions: try getCASPluginOptions())
179180
}
180-
return fallbackToFrontend
181+
return false
181182
}
182183

183184
static func sanitizeCommandForLibScanInvocation(_ command: inout [String]) {

Tests/SwiftDriverTests/CachingBuildTests.swift

Lines changed: 15 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -499,13 +499,9 @@ final class CachingBuildTests: XCTestCase {
499499
try driver.run(jobs: jobs)
500500
XCTAssertFalse(driver.diagnosticEngine.hasErrors)
501501

502-
let scanLibPath = try XCTUnwrap(driver.toolchain.lookupSwiftScanLib())
503-
guard try dependencyOracle
504-
.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
505-
swiftScanLibPath: scanLibPath) else {
506-
XCTFail("Dependency scanner library not found")
507-
return
508-
}
502+
let scanLibPath = try XCTUnwrap(driver.getSwiftScanLibPath())
503+
try dependencyOracle.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
504+
swiftScanLibPath: scanLibPath)
509505

510506
let cas = try dependencyOracle.getOrCreateCAS(pluginPath: nil, onDiskPath: casPath, pluginOptions: [])
511507
if let driverCAS = driver.cas {
@@ -558,13 +554,9 @@ final class CachingBuildTests: XCTestCase {
558554
env: ProcessEnv.vars,
559555
interModuleDependencyOracle: dependencyOracle)
560556

561-
let scanLibPath = try XCTUnwrap(fooBuildDriver.toolchain.lookupSwiftScanLib())
562-
guard try dependencyOracle
563-
.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
564-
swiftScanLibPath: scanLibPath) else {
565-
XCTFail("Dependency scanner library not found")
566-
return
567-
}
557+
let scanLibPath = try XCTUnwrap(fooBuildDriver.getSwiftScanLibPath())
558+
try dependencyOracle.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
559+
swiftScanLibPath: scanLibPath)
568560
guard try dependencyOracle.supportsBinaryModuleHeaderDependencies() else {
569561
throw XCTSkip("libSwiftScan does not support binary module header dependencies.")
570562
}
@@ -630,13 +622,9 @@ final class CachingBuildTests: XCTestCase {
630622
main.nativePathString(escaped: true)] + sdkArgumentsForTesting,
631623
env: ProcessEnv.vars,
632624
interModuleDependencyOracle: dependencyOracle)
633-
let scanLibPath = try XCTUnwrap(driver.toolchain.lookupSwiftScanLib())
634-
guard try dependencyOracle
635-
.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
636-
swiftScanLibPath: scanLibPath) else {
637-
XCTFail("Dependency scanner library not found")
638-
return
639-
}
625+
let scanLibPath = try XCTUnwrap(driver.getSwiftScanLibPath())
626+
try dependencyOracle.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
627+
swiftScanLibPath: scanLibPath)
640628
let resolver = try ArgsResolver(fileSystem: localFileSystem)
641629
var scannerCommand = try driver.dependencyScannerInvocationCommand().1.map { try resolver.resolve($0) }
642630
// We generate full swiftc -frontend -scan-dependencies invocations in order to also be
@@ -770,13 +758,9 @@ final class CachingBuildTests: XCTestCase {
770758
guard driver.isFrontendArgSupported(.scannerPrefixMap) else {
771759
throw XCTSkip("frontend doesn't support prefix map")
772760
}
773-
let scanLibPath = try XCTUnwrap(driver.toolchain.lookupSwiftScanLib())
774-
guard try dependencyOracle
775-
.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
776-
swiftScanLibPath: scanLibPath) else {
777-
XCTFail("Dependency scanner library not found")
778-
return
779-
}
761+
let scanLibPath = try XCTUnwrap(driver.getSwiftScanLibPath())
762+
try dependencyOracle.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
763+
swiftScanLibPath: scanLibPath)
780764
let resolver = try ArgsResolver(fileSystem: localFileSystem)
781765
let scannerCommand = try driver.dependencyScannerInvocationCommand().1.map { try resolver.resolve($0) }
782766

@@ -841,13 +825,9 @@ final class CachingBuildTests: XCTestCase {
841825
try driver.run(jobs: jobs)
842826
XCTAssertFalse(driver.diagnosticEngine.hasErrors)
843827

844-
let scanLibPath = try XCTUnwrap(driver.toolchain.lookupSwiftScanLib())
845-
guard try dependencyOracle
846-
.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
847-
swiftScanLibPath: scanLibPath) else {
848-
XCTFail("Dependency scanner library not found")
849-
return
850-
}
828+
let scanLibPath = try XCTUnwrap(driver.getSwiftScanLibPath())
829+
try dependencyOracle.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
830+
swiftScanLibPath: scanLibPath)
851831

852832
let cas = try dependencyOracle.getOrCreateCAS(pluginPath: nil, onDiskPath: casPath, pluginOptions: [])
853833
if let driverCAS = driver.cas {

Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift

Lines changed: 16 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -903,12 +903,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
903903
// queries.
904904
let dependencyOracle = InterModuleDependencyOracle()
905905
let scanLibPath = try XCTUnwrap(toolchain.lookupSwiftScanLib())
906-
guard try dependencyOracle
907-
.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
908-
swiftScanLibPath: scanLibPath) else {
909-
XCTFail("Dependency scanner library not found")
910-
return
911-
}
906+
try dependencyOracle.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
907+
swiftScanLibPath: scanLibPath)
912908

913909
try withTemporaryDirectory { path in
914910
let main = path.appending(component: "foo.swift")
@@ -1083,12 +1079,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
10831079
// 2. Run a dependency scan to find the just-built module
10841080
let dependencyOracle = InterModuleDependencyOracle()
10851081
let scanLibPath = try XCTUnwrap(toolchain.lookupSwiftScanLib())
1086-
guard try dependencyOracle
1087-
.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
1088-
swiftScanLibPath: scanLibPath) else {
1089-
XCTFail("Dependency scanner library not found")
1090-
return
1091-
}
1082+
try dependencyOracle.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
1083+
swiftScanLibPath: scanLibPath)
10921084
guard try dependencyOracle.supportsBinaryFrameworkDependencies() else {
10931085
throw XCTSkip("libSwiftScan does not support framework binary dependency reporting.")
10941086
}
@@ -1184,12 +1176,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
11841176
// queries.
11851177
let dependencyOracle = InterModuleDependencyOracle()
11861178
let scanLibPath = try XCTUnwrap(toolchain.lookupSwiftScanLib())
1187-
guard try dependencyOracle
1188-
.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
1189-
swiftScanLibPath: scanLibPath) else {
1190-
XCTFail("Dependency scanner library not found")
1191-
return
1192-
}
1179+
try dependencyOracle.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
1180+
swiftScanLibPath: scanLibPath)
11931181

11941182
// Create a simple test case.
11951183
try withTemporaryDirectory { path in
@@ -1293,12 +1281,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
12931281
// queries.
12941282
let dependencyOracle = InterModuleDependencyOracle()
12951283
let scanLibPath = try XCTUnwrap(toolchain.lookupSwiftScanLib())
1296-
guard try dependencyOracle
1297-
.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
1298-
swiftScanLibPath: scanLibPath) else {
1299-
XCTFail("Dependency scanner library not found")
1300-
return
1301-
}
1284+
try dependencyOracle.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
1285+
swiftScanLibPath: scanLibPath)
13021286
guard try dependencyOracle.supportsScannerDiagnostics() else {
13031287
throw XCTSkip("libSwiftScan does not support diagnostics query.")
13041288
}
@@ -1361,12 +1345,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
13611345
// queries.
13621346
let dependencyOracle = InterModuleDependencyOracle()
13631347
let scanLibPath = try XCTUnwrap(toolchain.lookupSwiftScanLib())
1364-
guard try dependencyOracle
1365-
.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
1366-
swiftScanLibPath: scanLibPath) else {
1367-
XCTFail("Dependency scanner library not found")
1368-
return
1369-
}
1348+
try dependencyOracle.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
1349+
swiftScanLibPath: scanLibPath)
13701350

13711351
// Create a simple test case.
13721352
try withTemporaryDirectory { path in
@@ -1566,12 +1546,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
15661546
let (stdlibPath, shimsPath, toolchain, _) = try getDriverArtifactsForScanning()
15671547
let dependencyOracle = InterModuleDependencyOracle()
15681548
let scanLibPath = try XCTUnwrap(toolchain.lookupSwiftScanLib())
1569-
guard try dependencyOracle
1570-
.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
1571-
swiftScanLibPath: scanLibPath) else {
1572-
XCTFail("Dependency scanner library not found")
1573-
return
1574-
}
1549+
try dependencyOracle.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
1550+
swiftScanLibPath: scanLibPath)
15751551
// Create a simple test case.
15761552
try withTemporaryDirectory { path in
15771553
let main = path.appending(component: "testDependencyScanning.swift")
@@ -1668,12 +1644,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
16681644
let scanLibPath = try XCTUnwrap(toolchain.lookupSwiftScanLib())
16691645
// Run the first scan and serialize the cache contents.
16701646
let firstDependencyOracle = InterModuleDependencyOracle()
1671-
guard try firstDependencyOracle
1672-
.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
1673-
swiftScanLibPath: scanLibPath) else {
1674-
XCTFail("Dependency scanner library not found")
1675-
return
1676-
}
1647+
try firstDependencyOracle.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
1648+
swiftScanLibPath: scanLibPath)
16771649

16781650
let firstScanGraph =
16791651
try firstDependencyOracle.getDependencies(workingDirectory: path,
@@ -1682,12 +1654,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
16821654

16831655
// Run the second scan, re-using the serialized cache contents.
16841656
let secondDependencyOracle = InterModuleDependencyOracle()
1685-
guard try secondDependencyOracle
1686-
.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
1687-
swiftScanLibPath: scanLibPath) else {
1688-
XCTFail("Dependency scanner library not found")
1689-
return
1690-
}
1657+
try secondDependencyOracle.verifyOrCreateScannerInstance(fileSystem: localFileSystem,
1658+
swiftScanLibPath: scanLibPath)
16911659
XCTAssertFalse(secondDependencyOracle.loadScannerCache(from: cacheSavePath))
16921660
let secondScanGraph =
16931661
try secondDependencyOracle.getDependencies(workingDirectory: path,

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5130,7 +5130,7 @@ final class SwiftDriverTests: XCTestCase {
51305130
swiftCompilerPrefixArgs: [])
51315131
var printTargetInfoCommand = try Driver.itemizedJobCommand(of: printTargetInfoJob, useResponseFiles: .disabled, using: ArgsResolver(fileSystem: InMemoryFileSystem()))
51325132
Driver.sanitizeCommandForLibScanInvocation(&printTargetInfoCommand)
5133-
let swiftScanLibPath = try XCTUnwrap(driver.toolchain.lookupSwiftScanLib())
5133+
let swiftScanLibPath = try XCTUnwrap(driver.getSwiftScanLibPath())
51345134
if localFileSystem.exists(swiftScanLibPath) {
51355135
let libSwiftScanInstance = try SwiftScan(dylib: swiftScanLibPath)
51365136
if libSwiftScanInstance.canQueryTargetInfo() {
@@ -5150,7 +5150,7 @@ final class SwiftDriverTests: XCTestCase {
51505150
swiftCompilerPrefixArgs: [])
51515151
var printTargetInfoCommand = try Driver.itemizedJobCommand(of: printTargetInfoJob, useResponseFiles: .disabled, using: ArgsResolver(fileSystem: InMemoryFileSystem()))
51525152
Driver.sanitizeCommandForLibScanInvocation(&printTargetInfoCommand)
5153-
let swiftScanLibPath = try XCTUnwrap(driver.toolchain.lookupSwiftScanLib())
5153+
let swiftScanLibPath = try XCTUnwrap(driver.getSwiftScanLibPath())
51545154
if localFileSystem.exists(swiftScanLibPath) {
51555155
let libSwiftScanInstance = try SwiftScan(dylib: swiftScanLibPath)
51565156
if libSwiftScanInstance.canQueryTargetInfo() {

0 commit comments

Comments
 (0)