Skip to content

Commit 3f49c7f

Browse files
committed
Support module wrapping for debugging on Linux
1 parent fba6877 commit 3f49c7f

File tree

6 files changed

+114
-4
lines changed

6 files changed

+114
-4
lines changed

Sources/SwiftDriver/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ add_library(SwiftDriver
4949
Jobs/Job.swift
5050
Jobs/LinkJob.swift
5151
Jobs/MergeModuleJob.swift
52+
Jobs/ModuleWrapJob.swift
5253
Jobs/Planning.swift
5354
Jobs/PrintTargetInfoJob.swift
5455
Jobs/ReplJob.swift

Sources/SwiftDriver/Jobs/Job.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public struct Job: Codable, Equatable, Hashable {
2323
case autolinkExtract = "autolink-extract"
2424
case emitModule = "emit-module"
2525
case generatePCH = "generate-pch"
26+
case moduleWrap = "module-wrap"
2627

2728
/// Generate a compiled Clang module.
2829
case generatePCM = "generate-pcm"
@@ -145,6 +146,9 @@ extension Job : CustomStringConvertible {
145146
case .generatePCH:
146147
return "Compiling bridging header \(displayInputs.first?.file.basename ?? "")"
147148

149+
case .moduleWrap:
150+
return "Wrapping Swift module \(moduleName)"
151+
148152
case .generatePCM:
149153
return "Compiling Clang module \(displayInputs.first?.file.basename ?? "")"
150154

@@ -184,7 +188,7 @@ extension Job.Kind {
184188
.versionRequest, .scanDependencies:
185189
return true
186190

187-
case .autolinkExtract, .generateDSYM, .help, .link, .verifyDebugInfo:
191+
case .autolinkExtract, .generateDSYM, .help, .link, .verifyDebugInfo, .moduleWrap:
188192
return false
189193
}
190194
}
@@ -197,7 +201,8 @@ extension Job.Kind {
197201
case .backend, .mergeModule, .emitModule, .generatePCH,
198202
.generatePCM, .interpret, .repl, .printTargetInfo,
199203
.versionRequest, .autolinkExtract, .generateDSYM,
200-
.help, .link, .verifyDebugInfo, .scanDependencies:
204+
.help, .link, .verifyDebugInfo, .scanDependencies,
205+
.moduleWrap:
201206
return false
202207
}
203208
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//===--------------- ModuleWrapJob.swift - Swift Module Wrapping ----------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
extension Driver {
14+
mutating func moduleWrapJob(moduleInput: TypedVirtualPath) throws -> Job {
15+
var commandLine: [Job.ArgTemplate] = swiftCompilerPrefixArgs.map { Job.ArgTemplate.flag($0) }
16+
17+
commandLine.appendFlags("-modulewrap")
18+
19+
// Add the input.
20+
commandLine.append(.path(moduleInput.file))
21+
assert(compilerOutputType == .object, "-modulewrap mode only produces object files")
22+
23+
commandLine.appendFlags("-target", targetTriple.triple)
24+
25+
let outputPath = try moduleInput.file.replacingExtension(with: .object)
26+
commandLine.appendFlag("-o")
27+
commandLine.appendPath(outputPath)
28+
29+
return Job(
30+
moduleName: moduleOutputInfo.name,
31+
kind: .moduleWrap,
32+
tool: .absolute(try toolchain.getToolPath(.swiftCompiler)),
33+
commandLine: commandLine,
34+
inputs: [moduleInput],
35+
outputs: [.init(file: outputPath, type: .object)],
36+
supportsResponseFiles: true
37+
)
38+
}
39+
}

Sources/SwiftDriver/Jobs/Planning.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,10 @@ extension Driver {
188188
jobs.append(contentsOf: backendJobs)
189189

190190
// Plan the merge-module job, if there are module inputs.
191+
var mergeJob: Job?
191192
if moduleOutputInfo.output != nil && !moduleInputs.isEmpty && compilerMode.usesPrimaryFileInputs {
192-
jobs.append(try mergeModuleJob(inputs: moduleInputs))
193+
mergeJob = try mergeModuleJob(inputs: moduleInputs)
194+
jobs.append(mergeJob!)
193195
}
194196

195197
// If we need to autolink-extract, do so.
@@ -199,6 +201,20 @@ extension Driver {
199201
jobs.append(autolinkExtractJob)
200202
}
201203

204+
if let mergeJob = mergeJob, debugInfo.level == .astTypes {
205+
if targetTriple.objectFormat != .macho {
206+
// Module wrapping is required.
207+
let mergeModuleOutputs = mergeJob.outputs.filter { $0.type == .swiftModule }
208+
assert(mergeModuleOutputs.count == 1,
209+
"Merge module job should only have one swiftmodule output")
210+
let wrapJob = try moduleWrapJob(moduleInput: mergeModuleOutputs[0])
211+
linkerInputs.append(contentsOf: wrapJob.outputs)
212+
jobs.append(wrapJob)
213+
} else {
214+
linkerInputs.append(contentsOf: mergeJob.outputs)
215+
}
216+
}
217+
202218
// If we should link, do so.
203219
var link: Job?
204220
if linkerOutputType != nil && !linkerInputs.isEmpty {

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,52 @@ final class SwiftDriverTests: XCTestCase {
13091309
}
13101310
}
13111311

1312+
func testModuleWrapJob() throws {
1313+
do {
1314+
var driver = try Driver(args: ["swiftc", "-target", "x86_64-unknown-linux-gnu", "-g", "foo.swift"])
1315+
let plannedJobs = try driver.planBuild()
1316+
XCTAssertEqual(plannedJobs.count, 4)
1317+
// FIXME: There should also be an autolink-extract job. It looks like our
1318+
// triple parsing code is not detecting the object file format correctly.
1319+
XCTAssertEqual(plannedJobs.map { $0.kind }, [.compile, .mergeModule, .moduleWrap, .link])
1320+
XCTAssertEqual(plannedJobs[2].inputs.count, 1)
1321+
XCTAssertEqual(plannedJobs[2].inputs.count, 1)
1322+
XCTAssertTrue(plannedJobs[2].commandLine.contains(subsequence: ["-target", "x86_64-unknown-linux-gnu"]))
1323+
XCTAssertTrue(plannedJobs[1].outputs.contains(plannedJobs[2].inputs.first!))
1324+
XCTAssertTrue(plannedJobs[3].inputs.contains(plannedJobs[2].outputs.first!))
1325+
}
1326+
1327+
do {
1328+
var driver = try Driver(args: ["swiftc", "-target", "x86_64-apple-macosx10.15", "-g", "foo.swift"])
1329+
let plannedJobs = try driver.planBuild()
1330+
XCTAssertEqual(plannedJobs.count, 4)
1331+
// No module wrapping with Mach-O.
1332+
// FIXME: There should also be an autolink-extract job. It looks like our
1333+
// triple parsing code is not detecting the object file format correctly.
1334+
XCTAssertEqual(plannedJobs.map { $0.kind }, [.compile, .mergeModule, .link, .generateDSYM])
1335+
}
1336+
1337+
do {
1338+
var driver = try Driver(args: ["swiftc", "-target", "x86_64-unknown-linux-gnu", "foo.swift"])
1339+
let plannedJobs = try driver.planBuild()
1340+
XCTAssertEqual(plannedJobs.count, 2)
1341+
// No merge module/module wrap jobs.
1342+
// FIXME: There should also be an autolink-extract job. It looks like our
1343+
// triple parsing code is not detecting the object file format correctly.
1344+
XCTAssertEqual(plannedJobs.map { $0.kind }, [.compile, .link])
1345+
}
1346+
1347+
do {
1348+
var driver = try Driver(args: ["swiftc", "-target", "x86_64-unknown-linux-gnu", "-gdwarf-types", "foo.swift"])
1349+
let plannedJobs = try driver.planBuild()
1350+
XCTAssertEqual(plannedJobs.count, 3)
1351+
// Merge module, but no module wrapping.
1352+
// FIXME: There should also be an autolink-extract job. It looks like our
1353+
// triple parsing code is not detecting the object file format correctly.
1354+
XCTAssertEqual(plannedJobs.map { $0.kind }, [.compile, .mergeModule, .link])
1355+
}
1356+
}
1357+
13121358
func testRepl() throws {
13131359

13141360
func isLLDBREPLFlag(_ arg: Job.ArgTemplate) -> Bool {
@@ -1562,7 +1608,8 @@ final class SwiftDriverTests: XCTestCase {
15621608
func testDSYMGeneration() throws {
15631609
let commonArgs = [
15641610
"swiftc", "foo.swift", "bar.swift",
1565-
"-emit-executable", "-module-name", "Test"
1611+
"-emit-executable", "-module-name", "Test",
1612+
"-target", "x86_64-apple-macosx10.14"
15661613
]
15671614

15681615
do {

Tests/SwiftDriverTests/XCTestManifests.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ extension ExplicitModuleBuildTests {
2121
("testExplicitModuleBuildJobs", testExplicitModuleBuildJobs),
2222
("testExplicitSwiftModuleMap", testExplicitSwiftModuleMap),
2323
("testModuleDependencyBuildCommandGeneration", testModuleDependencyBuildCommandGeneration),
24+
("testModuleDependencyWithExternalCommandGeneration", testModuleDependencyWithExternalCommandGeneration),
2425
]
2526
}
2627

@@ -107,6 +108,7 @@ extension SwiftDriverTests {
107108
("testModuleNameFallbacks", testModuleNameFallbacks),
108109
("testModuleNaming", testModuleNaming),
109110
("testModuleSettings", testModuleSettings),
111+
("testModuleWrapJob", testModuleWrapJob),
110112
("testMultiThreadedWholeModuleOptimizationCompiles", testMultiThreadedWholeModuleOptimizationCompiles),
111113
("testMultithreading", testMultithreading),
112114
("testMultithreadingDiagnostics", testMultithreadingDiagnostics),

0 commit comments

Comments
 (0)