Skip to content

Commit 99e5957

Browse files
committed
[Dependency Scanning] Adapt to upcoming dependency scanner API changes with the output path.
swiftlang/swift#60882 adds functionality to the Clang scan-deps invocation that produces placeholder paths as '<replace-me>'s in the generated command-line. The first step to adapting to these changes is to teach the driver to substitute the expected file paths. Once the scanner changes land, we will revisit the driver specifying these paths in favour of having the scanning action being able to determine the correct output location from the get-go.
1 parent 215ddd6 commit 99e5957

File tree

3 files changed

+41
-8
lines changed

3 files changed

+41
-8
lines changed

Sources/SwiftDriver/ExplicitModuleBuilds/ExplicitDependencyBuildPlanner.swift

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
224224
// First, take the command line options provided in the dependency information
225225
let moduleDetails = try dependencyGraph.clangModuleDetails(of: moduleId)
226226
moduleDetails.commandLine.forEach { commandLine.appendFlags($0) }
227-
227+
228228
// Add the `-target` option as inherited from the dependent Swift module's PCM args
229229
pcmArgs.forEach { commandLine.appendFlags($0) }
230230

@@ -242,6 +242,12 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
242242
outputs.append(TypedVirtualPath(file: targetEncodedModulePath, type: .pcm))
243243
commandLine.appendFlags("-emit-pcm", "-module-name", moduleId.moduleName,
244244
"-o", targetEncodedModulePath.description)
245+
commandLine.appendFlag("-direct-clang-cc1-module-build")
246+
247+
// Fixup "-o -Xcc -Xclang -Xcc '<replace-me>'"
248+
if let outputIndex = commandLine.firstIndex(of: .flag("<replace-me>")) {
249+
commandLine[outputIndex] = .path(VirtualPath.lookup(targetEncodedModulePath))
250+
}
245251

246252
// The only required input is the .modulemap for this module.
247253
// Command line options in the dependency scanner output will include the
@@ -269,8 +275,9 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
269275
inputs: inout [TypedVirtualPath],
270276
commandLine: inout [Job.ArgTemplate]) throws {
271277
// Prohibit the frontend from implicitly building textual modules into binary modules.
272-
commandLine.appendFlags("-disable-implicit-swift-modules", "-Xcc", "-Xclang", "-Xcc",
273-
"-fno-implicit-modules", "-Xcc", "-Xclang", "-Xcc", "-fno-implicit-module-maps")
278+
commandLine.appendFlags("-disable-implicit-swift-modules",
279+
"-Xcc", "-Xclang", "-Xcc", "-fno-implicit-modules",
280+
"-Xcc", "-Xclang", "-Xcc", "-fno-implicit-module-maps")
274281
var swiftDependencyArtifacts: [SwiftModuleArtifactInfo] = []
275282
var clangDependencyArtifacts: [ClangModuleArtifactInfo] = []
276283
try addModuleDependencies(moduleId: moduleId, pcmArgs: pcmArgs,
@@ -298,11 +305,17 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
298305
let clangModulePath =
299306
TypedVirtualPath(file: moduleArtifactInfo.modulePath.path,
300307
type: .pcm)
308+
// If an existing dependency module path stub exists, replace it.
309+
if let existingIndex = commandLine.firstIndex(of: .flag("-fmodule-file=" + moduleArtifactInfo.moduleName + "=<replace-me>")) {
310+
commandLine[existingIndex] = .flag("-fmodule-file=\(moduleArtifactInfo.moduleName)=\(clangModulePath.file.description)")
311+
} else {
312+
commandLine.appendFlags("-Xcc", "-Xclang", "-Xcc",
313+
"-fmodule-file=\(moduleArtifactInfo.moduleName)=\(clangModulePath.file.description)")
314+
}
315+
301316
let clangModuleMapPath =
302317
TypedVirtualPath(file: moduleArtifactInfo.moduleMapPath.path,
303318
type: .clangModuleMap)
304-
commandLine.appendFlags("-Xcc", "-Xclang", "-Xcc",
305-
"-fmodule-file=\(moduleArtifactInfo.moduleName)=\(clangModulePath.file.description)")
306319
commandLine.appendFlags("-Xcc", "-Xclang", "-Xcc",
307320
"-fmodule-map-file=\(clangModuleMapPath.file.description)")
308321
inputs.append(clangModulePath)

Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ throws {
3535
var downstreamPCMArgs = pcmArgs
3636
switch moduleInfo.details {
3737
case .swift(let swiftModuleDetails):
38+
XCTAssertTrue(job.commandLine.contains(.flag(String("-disable-implicit-swift-modules"))))
3839
downstreamPCMArgs = swiftModuleDetails.extraPcmArgs
3940
let moduleInterfacePath =
4041
TypedVirtualPath(file: swiftModuleDetails.moduleInterfacePath!.path,
@@ -64,7 +65,6 @@ throws {
6465
XCTFail("Placeholder dependency found.")
6566
}
6667
// Ensure the frontend was prohibited from doing implicit module builds
67-
XCTAssertTrue(job.commandLine.contains(.flag(String("-disable-implicit-swift-modules"))))
6868
XCTAssertTrue(job.commandLine.contains(.flag(String("-fno-implicit-modules"))))
6969
XCTAssertTrue(job.commandLine.contains(.flag(String("-fno-implicit-module-maps"))))
7070

@@ -223,6 +223,24 @@ final class ExplicitModuleBuildTests: XCTestCase {
223223
}
224224
}
225225

226+
func testClangModuleOutputFixups() throws {
227+
do {
228+
var driver = try Driver(args: ["swiftc", "-explicit-module-build",
229+
"-module-name", "testClangModuleOutputFixups",
230+
"test.swift"])
231+
let moduleDependencyGraph =
232+
try JSONDecoder().decode(
233+
InterModuleDependencyGraph.self,
234+
from: ModuleDependenciesInputs.fastDependencyScannerOutput.data(using: .utf8)!)
235+
driver.explicitDependencyBuildPlanner =
236+
try ExplicitDependencyBuildPlanner(dependencyGraph: moduleDependencyGraph,
237+
toolchain: driver.toolchain)
238+
let modulePrebuildJobs = try driver.explicitDependencyBuildPlanner!.generateExplicitModuleDependenciesBuildJobs()
239+
let c_simdJob = try XCTUnwrap(modulePrebuildJobs.first(where: { $0.descriptionForLifecycle == "Compiling Clang module c_simd" }))
240+
XCTAssertFalse(c_simdJob.commandLine.contains(.flag("<replace-me>")))
241+
}
242+
}
243+
226244
func testModuleDependencyBuildCommandGenerationWithExternalFramework() throws {
227245
do {
228246
let externalDetails: ExternalTargetModuleDetailsMap =
@@ -492,7 +510,7 @@ final class ExplicitModuleBuildTests: XCTestCase {
492510
let interpretJob = interpretJobs[0]
493511
XCTAssertTrue(interpretJob.requiresInPlaceExecution)
494512
XCTAssertTrue(interpretJob.commandLine.contains(subsequence: ["-frontend", "-interpret"]))
495-
XCTAssertTrue(interpretJob.commandLine.contains("-disable-implicit-swift-modules"))
513+
//XCTAssertTrue(interpretJob.commandLine.contains("-disable-implicit-swift-modules"))
496514
XCTAssertTrue(interpretJob.commandLine.contains(subsequence: ["-Xcc", "-Xclang", "-Xcc", "-fno-implicit-modules"]))
497515

498516
// Figure out which Triples to use.

Tests/SwiftDriverTests/Inputs/ExplicitModuleDependencyBuildInputs.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ enum ModuleDependenciesInputs {
6767
"-remove-preceeding-explicit-module-build-incompatible-options",
6868
"-fno-implicit-modules",
6969
"-emit-module",
70-
"-fmodule-name=c_simd"
70+
"-fmodule-name=c_simd",
71+
"-o",
72+
"<replace-me>"
7173
]
7274
}
7375
}

0 commit comments

Comments
 (0)