Skip to content

Commit b529ffe

Browse files
committed
Implement -debug-module-path for implicit modules in swift-driver
There is no fundamental technical reason to restrict this feature to explict modules only, so this patch adds support for passing the correct -debug-module-path also to implicit builds. rdar://168256846
1 parent e2fb42b commit b529ffe

3 files changed

Lines changed: 61 additions & 28 deletions

File tree

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,15 @@ extension Driver {
109109
jobNeedPathRemap = false
110110
}
111111

112-
if isPlanJobForExplicitModule && forObject && isFrontendArgSupported(.debugModulePath),
113-
let explicitModulePlanner {
114-
let mainModule = explicitModulePlanner.dependencyGraph.mainModule
115-
let pathHandle = moduleOutputInfo.output?.outputPath ?? mainModule.modulePath.path
116-
let path = VirtualPath.lookup(pathHandle)
117-
try addPathOption(option: .debugModulePath, path: path, to: &commandLine, remap: jobNeedPathRemap)
112+
// Add the -debug-module-path option to the compile job.
113+
// If modulePathHandle is nil, this build doesn't produce a Swift module.
114+
if forObject && isFrontendArgSupported(.debugModulePath),
115+
var modulePathHandle = moduleOutputInfo.output?.outputPath {
116+
// Recompute the module path based on the module name, because this is effectively passing the output
117+
// of the module merge action which depends on the compile action.
118+
let moduleBase : VirtualPath = VirtualPath.lookup(modulePathHandle).parentDirectory.appending(component: moduleOutputInfo.name)
119+
modulePathHandle = try moduleBase.replacingExtension(with: .swiftModule).intern()
120+
try addPathOption(option: .debugModulePath, path: VirtualPath.lookup(modulePathHandle), to: &commandLine, remap: jobNeedPathRemap)
118121
}
119122

120123
// Check if dependency scanner has put the job into direct clang cc1 mode.

Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -716,10 +716,6 @@ final class ExplicitModuleBuildTests: XCTestCase {
716716
for job in jobs {
717717
XCTAssertEqual(job.outputs.count, 1)
718718
let outputFilePath = job.outputs[0].file
719-
if job.kind == .compile && driver.isFrontendArgSupported(.debugModulePath) {
720-
XCTAssertTrue(job.commandLine.contains(subsequence: ["-debug-module-path", try toPathOption("testExplicitModuleBuildJobs.swiftmodule")]))
721-
722-
}
723719

724720
// Swift dependencies
725721
if let outputFileExtension = outputFilePath.extension,
@@ -782,6 +778,38 @@ final class ExplicitModuleBuildTests: XCTestCase {
782778
}
783779
}
784780

781+
/// Test the -debug-module-path option in expilicit builds.
782+
func testExplicitModuleBuildDebugModulePath() throws {
783+
let (stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning()
784+
try withTemporaryDirectory { path in
785+
let main = path.appending(component: "testExplicitModuleBuildJobs.swift")
786+
try localFileSystem.writeFileContents(main, bytes:
787+
"""
788+
import C;
789+
"""
790+
)
791+
792+
let swiftModuleInterfacesPath: AbsolutePath =
793+
try testInputsPath.appending(component: "ExplicitModuleBuilds")
794+
.appending(component: "Swift")
795+
let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? []
796+
var driver = try Driver(args: ["swiftc",
797+
"-g",
798+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: false),
799+
"-I", stdlibPath.nativePathString(escaped: false),
800+
"-I", shimsPath.nativePathString(escaped: false),
801+
"-explicit-module-build",
802+
"-disable-implicit-concurrency-module-import",
803+
"-disable-implicit-string-processing-module-import",
804+
main.nativePathString(escaped: false)] + sdkArgumentsForTesting)
805+
guard driver.isFrontendArgSupported(.debugModulePath) else { return }
806+
let jobs = try driver.planBuild()
807+
try jobs.filter { $0.kind == .compile }.forEach { job in
808+
XCTAssertTrue(job.commandLine.contains(subsequence: ["-debug-module-path", try toPathOption("testExplicitModuleBuildJobs.swiftmodule")]))
809+
}
810+
}
811+
}
812+
785813
func testRegisterModuleDependencyFlag() throws {
786814
let (stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning()
787815
try withTemporaryDirectory { path in
@@ -1100,24 +1128,6 @@ final class ExplicitModuleBuildTests: XCTestCase {
11001128
let baseName = "testExplicitModuleVerifyInterfaceJobs"
11011129
XCTAssertTrue(matchTemporary(outputFilePath, basename: baseName, fileExtension: "o") ||
11021130
matchTemporary(outputFilePath, basename: baseName, fileExtension: "autolink"))
1103-
if outputFilePath.extension == FileType.object.rawValue && driver.isFrontendArgSupported(.debugModulePath) {
1104-
// Check that this is an absolute path pointing to the temporary directory.
1105-
var found : Bool = false
1106-
for arg in job.commandLine {
1107-
if !found && arg == "-debug-module-path" {
1108-
found = true
1109-
} else if found {
1110-
if case let .path(vpath) = arg {
1111-
XCTAssertTrue(vpath.isTemporary)
1112-
XCTAssertTrue(vpath.extension == FileType.swiftModule.rawValue)
1113-
} else {
1114-
XCTFail("argument is not a path")
1115-
}
1116-
break
1117-
}
1118-
}
1119-
XCTAssertTrue(found)
1120-
}
11211131
default:
11221132
XCTFail("Unexpected module dependency build job output: \(outputFilePath)")
11231133
}

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4129,6 +4129,26 @@ final class SwiftDriverTests: XCTestCase {
41294129
}
41304130
}
41314131

4132+
4133+
func testDebugModulePath() throws {
4134+
do {
4135+
var driver = try Driver(args: ["swiftc", "-target", "arm64-unknown-macos26", "-g", "foo.swift"])
4136+
let plannedJobs = try driver.planBuild()
4137+
let compileJob = try plannedJobs.findJob(.compile)
4138+
// This needs to be "foo.swiftmodule", not the unmerged "foo-1.swiftmodule".
4139+
XCTAssertJobInvocationMatches(compileJob, .flag("-debug-module-path"), .path(try .temporary(RelativePath(validating: "foo")).replacingExtension(with: .swiftModule)))
4140+
}
4141+
// Unfortunately this depends on dsymutil.
4142+
#if os(macOS)
4143+
do {
4144+
var driver = try Driver(args: ["swiftc", "-target", "arm64-unknown-macos26", "-g", "foo.swift"])
4145+
let plannedJobs = try driver.planBuild()
4146+
let compileJob = try plannedJobs.findJob(.compile)
4147+
XCTAssertJobInvocationMatches(compileJob, .flag("-debug-module-path"), .path(try .temporary(RelativePath(validating: "foo")).replacingExtension(with: .swiftModule)))
4148+
}
4149+
#endif
4150+
}
4151+
41324152
func testModuleWrapJob() throws {
41334153
// FIXME: These tests will fail when run on macOS, because
41344154
// swift-autolink-extract is not present

0 commit comments

Comments
 (0)