From 3c86960cc3df3520bf445b45556c998bd0dc48c9 Mon Sep 17 00:00:00 2001 From: Artem Chikin Date: Thu, 3 Aug 2023 16:50:26 -0700 Subject: [PATCH 1/2] [Dependency Scanning] Add option to specify a separate Clang Dependency scanner module cache. Clang dependency scanning produces scanner PCMs which we may want to live in a different filesystem location than the main build module cache. Resolves rdar://113222853 --- .../ModuleDependencyScanning.swift | 1 + Sources/SwiftOptions/Options.swift | 2 ++ .../ExplicitModuleBuildTests.swift | 22 +++++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift b/Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift index b9a840b8e..e42fd6635 100644 --- a/Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift +++ b/Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift @@ -121,6 +121,7 @@ public extension Driver { } try commandLine.appendLast(.clangIncludeTree, from: &parsedOptions) + try commandLine.appendLast(.clangScannerModuleCachePath, from: &parsedOptions) // Pass on the input files commandLine.append(contentsOf: inputFiles.filter { $0.type == .swift }.map { .path($0.file) }) diff --git a/Sources/SwiftOptions/Options.swift b/Sources/SwiftOptions/Options.swift index 656411779..b4d73ce6b 100644 --- a/Sources/SwiftOptions/Options.swift +++ b/Sources/SwiftOptions/Options.swift @@ -74,6 +74,7 @@ extension Option { public static let clangHeaderExposeModule: Option = Option("-clang-header-expose-module", .separate, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "=", helpText: "Allow the compiler to assume that APIs from the specified module are exposed to C/C++/Objective-C in another generated header, so that APIs in the current module that depend on declarations from the specified module can be exposed in the generated header.") public static let clangIncludeTreeRoot: Option = Option("-clang-include-tree-root", .separate, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "", helpText: "Clang Include Tree CASID") public static let clangIncludeTree: Option = Option("-clang-include-tree", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Use clang include tree") + public static let clangScannerModuleCachePath: Option = Option("-clang-scanner-module-cache-path", .separate, attributes: [.frontend, .doesNotAffectIncrementalBuild, .argumentIsPath], helpText: "Specifies the Clang dependency scanner module cache path") public static let clangTarget: Option = Option("-clang-target", .separate, attributes: [.frontend], helpText: "Separately set the target we should use for internal Clang instance") public static let codeCompleteCallPatternHeuristics: Option = Option("-code-complete-call-pattern-heuristics", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Use heuristics to guess whether we want call pattern completions") public static let codeCompleteInitsInPostfixExpr: Option = Option("-code-complete-inits-in-postfix-expr", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Include initializers when completing a postfix expression") @@ -867,6 +868,7 @@ extension Option { Option.clangHeaderExposeModule, Option.clangIncludeTreeRoot, Option.clangIncludeTree, + Option.clangScannerModuleCachePath, Option.clangTarget, Option.codeCompleteCallPatternHeuristics, Option.codeCompleteInitsInPostfixExpr, diff --git a/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift b/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift index b5f07e120..3deab32d8 100644 --- a/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift +++ b/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift @@ -1365,6 +1365,28 @@ final class ExplicitModuleBuildTests: XCTestCase { } } + /// Test that the scanner invocation does not rely in response files + func testDependencyScanningSeparateClangScanCache() throws { + try withTemporaryDirectory { path in + let scannerCachePath: AbsolutePath = path.appending(component: "ClangScannerCache") + let moduleCachePath: AbsolutePath = path.appending(component: "ModuleCache") + let main = path.appending(component: "testDependencyScanningSeparateClangScanCache.swift") + let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? [] + var driver = try Driver(args: ["swiftc", + "-explicit-module-build", + "-clang-scanner-module-cache-path", + scannerCachePath.nativePathString(escaped: true), + "-module-cache-path", + moduleCachePath.nativePathString(escaped: true), + "-working-directory", path.nativePathString(escaped: true), + main.nativePathString(escaped: true)] + sdkArgumentsForTesting, + env: ProcessEnv.vars) + let scannerJob = try driver.dependencyScanningJob() + XCTAssertTrue(scannerJob.commandLine.contains(subsequence: [.flag("-clang-scanner-module-cache-path"), + .path(.absolute(scannerCachePath))])) + } + } + func testDependencyScanningFailure() throws { let (stdlibPath, shimsPath, toolchain, _) = try getDriverArtifactsForScanning() From 03d396cc186db0db8c3063a4d373d0df80d8f700 Mon Sep 17 00:00:00 2001 From: Artem Chikin Date: Mon, 7 Aug 2023 11:08:14 -0700 Subject: [PATCH 2/2] Update Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift Co-authored-by: Allan Shortlidge --- .../ExplicitModuleBuilds/ModuleDependencyScanning.swift | 4 +++- Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift b/Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift index e42fd6635..b0971c81d 100644 --- a/Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift +++ b/Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift @@ -121,7 +121,9 @@ public extension Driver { } try commandLine.appendLast(.clangIncludeTree, from: &parsedOptions) - try commandLine.appendLast(.clangScannerModuleCachePath, from: &parsedOptions) + if isFrontendArgSupported(.clangScannerModuleCachePath) { + try commandLine.appendLast(.clangScannerModuleCachePath, from: &parsedOptions) + } // Pass on the input files commandLine.append(contentsOf: inputFiles.filter { $0.type == .swift }.map { .path($0.file) }) diff --git a/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift b/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift index 3deab32d8..523425044 100644 --- a/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift +++ b/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift @@ -1365,7 +1365,7 @@ final class ExplicitModuleBuildTests: XCTestCase { } } - /// Test that the scanner invocation does not rely in response files + /// Test that the scanner invocation does not rely on response files func testDependencyScanningSeparateClangScanCache() throws { try withTemporaryDirectory { path in let scannerCachePath: AbsolutePath = path.appending(component: "ClangScannerCache") @@ -1381,6 +1381,10 @@ final class ExplicitModuleBuildTests: XCTestCase { "-working-directory", path.nativePathString(escaped: true), main.nativePathString(escaped: true)] + sdkArgumentsForTesting, env: ProcessEnv.vars) + guard driver.isFrontendArgSupported(.clangScannerModuleCachePath) else { + throw XCTSkip("Skipping: compiler does not support '-clang-scanner-module-cache-path'") + } + let scannerJob = try driver.dependencyScanningJob() XCTAssertTrue(scannerJob.commandLine.contains(subsequence: [.flag("-clang-scanner-module-cache-path"), .path(.absolute(scannerCachePath))]))