Skip to content

Commit a5bb0b0

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 a5bb0b0

File tree

3 files changed

+41
-7
lines changed

3 files changed

+41
-7
lines changed

Sources/SwiftDriver/ExplicitModuleBuilds/ExplicitDependencyBuildPlanner.swift

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
145145
// First, take the command line options provided in the dependency information
146146
let moduleDetails = try dependencyGraph.swiftModuleDetails(of: moduleId)
147147
moduleDetails.commandLine?.forEach { commandLine.appendFlags($0) }
148+
// Prohibit implicit module loading
149+
commandLine.appendFlags("-disable-implicit-swift-modules",
150+
"-Xcc", "-Xclang", "-Xcc", "-fno-implicit-module-maps")
148151

149152
// Resolve all dependency module inputs for this Swift module
150153
try resolveExplicitModuleDependencies(moduleId: moduleId, pcmArgs: pcmArgs,
@@ -224,7 +227,9 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
224227
// First, take the command line options provided in the dependency information
225228
let moduleDetails = try dependencyGraph.clangModuleDetails(of: moduleId)
226229
moduleDetails.commandLine.forEach { commandLine.appendFlags($0) }
227-
230+
// Prohibit implicit module loading
231+
commandLine.appendFlags("-Xcc", "-Xclang", "-Xcc", "-fno-implicit-module-maps")
232+
228233
// Add the `-target` option as inherited from the dependent Swift module's PCM args
229234
pcmArgs.forEach { commandLine.appendFlags($0) }
230235

@@ -242,6 +247,12 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
242247
outputs.append(TypedVirtualPath(file: targetEncodedModulePath, type: .pcm))
243248
commandLine.appendFlags("-emit-pcm", "-module-name", moduleId.moduleName,
244249
"-o", targetEncodedModulePath.description)
250+
commandLine.appendFlag("-direct-clang-cc1-module-build")
251+
252+
// Fixup "-o -Xcc -Xclang -Xcc '<replace-me>'"
253+
if let outputIndex = commandLine.firstIndex(of: .flag("<replace-me>")) {
254+
commandLine[outputIndex] = .path(VirtualPath.lookup(targetEncodedModulePath))
255+
}
245256

246257
// The only required input is the .modulemap for this module.
247258
// Command line options in the dependency scanner output will include the
@@ -268,9 +279,6 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
268279
private mutating func resolveExplicitModuleDependencies(moduleId: ModuleDependencyId, pcmArgs: [String],
269280
inputs: inout [TypedVirtualPath],
270281
commandLine: inout [Job.ArgTemplate]) throws {
271-
// 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")
274282
var swiftDependencyArtifacts: [SwiftModuleArtifactInfo] = []
275283
var clangDependencyArtifacts: [ClangModuleArtifactInfo] = []
276284
try addModuleDependencies(moduleId: moduleId, pcmArgs: pcmArgs,
@@ -298,11 +306,17 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
298306
let clangModulePath =
299307
TypedVirtualPath(file: moduleArtifactInfo.modulePath.path,
300308
type: .pcm)
309+
// If an existing dependency module path stub exists, replace it.
310+
if let existingIndex = commandLine.firstIndex(of: .flag("-fmodule-file=" + moduleArtifactInfo.moduleName + "=<replace-me>")) {
311+
commandLine[existingIndex] = .flag("-fmodule-file=\(moduleArtifactInfo.moduleName)=\(clangModulePath.file.description)")
312+
} else {
313+
commandLine.appendFlags("-Xcc", "-Xclang", "-Xcc",
314+
"-fmodule-file=\(moduleArtifactInfo.moduleName)=\(clangModulePath.file.description)")
315+
}
316+
301317
let clangModuleMapPath =
302318
TypedVirtualPath(file: moduleArtifactInfo.moduleMapPath.path,
303319
type: .clangModuleMap)
304-
commandLine.appendFlags("-Xcc", "-Xclang", "-Xcc",
305-
"-fmodule-file=\(moduleArtifactInfo.moduleName)=\(clangModulePath.file.description)")
306320
commandLine.appendFlags("-Xcc", "-Xclang", "-Xcc",
307321
"-fmodule-map-file=\(clangModuleMapPath.file.description)")
308322
inputs.append(clangModulePath)

Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 =

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)