Skip to content

Commit b096a57

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 b096a57

File tree

3 files changed

+40
-8
lines changed

3 files changed

+40
-8
lines changed

Sources/SwiftDriver/ExplicitModuleBuilds/ExplicitDependencyBuildPlanner.swift

Lines changed: 17 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

@@ -243,6 +243,11 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
243243
commandLine.appendFlags("-emit-pcm", "-module-name", moduleId.moduleName,
244244
"-o", targetEncodedModulePath.description)
245245

246+
// Fixup "-o -Xcc -Xclang -Xcc '<replace-me>'"
247+
if let outputIndex = commandLine.firstIndex(of: .flag("<replace-me>")) {
248+
commandLine[outputIndex] = .path(VirtualPath.lookup(targetEncodedModulePath))
249+
}
250+
246251
// The only required input is the .modulemap for this module.
247252
// Command line options in the dependency scanner output will include the
248253
// required modulemap, so here we must only add it to the list of inputs.
@@ -269,8 +274,9 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
269274
inputs: inout [TypedVirtualPath],
270275
commandLine: inout [Job.ArgTemplate]) throws {
271276
// 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")
277+
commandLine.appendFlags("-disable-implicit-swift-modules",
278+
"-Xcc", "-Xclang", "-Xcc", "-fno-implicit-modules",
279+
"-Xcc", "-Xclang", "-Xcc", "-fno-implicit-module-maps")
274280
var swiftDependencyArtifacts: [SwiftModuleArtifactInfo] = []
275281
var clangDependencyArtifacts: [ClangModuleArtifactInfo] = []
276282
try addModuleDependencies(moduleId: moduleId, pcmArgs: pcmArgs,
@@ -298,11 +304,17 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
298304
let clangModulePath =
299305
TypedVirtualPath(file: moduleArtifactInfo.modulePath.path,
300306
type: .pcm)
307+
// If an existing dependency module path stub exists, replace it.
308+
if let existingIndex = commandLine.firstIndex(of: .flag("-fmodule-file=" + moduleArtifactInfo.moduleName + "=<replace-me>")) {
309+
commandLine[existingIndex] = .flag("-fmodule-file=\(moduleArtifactInfo.moduleName)=\(clangModulePath.file.description)")
310+
} else {
311+
commandLine.appendFlags("-Xcc", "-Xclang", "-Xcc",
312+
"-fmodule-file=\(moduleArtifactInfo.moduleName)=\(clangModulePath.file.description)")
313+
}
314+
301315
let clangModuleMapPath =
302316
TypedVirtualPath(file: moduleArtifactInfo.moduleMapPath.path,
303317
type: .clangModuleMap)
304-
commandLine.appendFlags("-Xcc", "-Xclang", "-Xcc",
305-
"-fmodule-file=\(moduleArtifactInfo.moduleName)=\(clangModulePath.file.description)")
306318
commandLine.appendFlags("-Xcc", "-Xclang", "-Xcc",
307319
"-fmodule-map-file=\(clangModuleMapPath.file.description)")
308320
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)