Skip to content

Commit aac7f4d

Browse files
authored
Merge pull request #615 from xymus/emit-module-verify
Verify module interfaces generated from emit-module jobs
2 parents 56808d3 + 3566656 commit aac7f4d

File tree

2 files changed

+61
-10
lines changed

2 files changed

+61
-10
lines changed

Sources/SwiftDriver/Jobs/Planning.swift

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ extension Driver {
104104

105105
try addPrecompileModuleDependenciesJobs(addJob: addJobBeforeCompiles)
106106
try addPrecompileBridgingHeaderJob(addJob: addJobBeforeCompiles)
107-
try addEmitModuleJob(addJob: addJobBeforeCompiles)
107+
try addEmitModuleJob(addJobBeforeCompiles: addJobBeforeCompiles, addJobAfterCompiles: addJobAfterCompiles)
108108
let linkerInputs = try addJobsFeedingLinker(
109109
addJobBeforeCompiles: addJobBeforeCompiles,
110110
addCompileJobGroup: addCompileJobGroup,
@@ -183,9 +183,11 @@ extension Driver {
183183
)
184184
}
185185

186-
private mutating func addEmitModuleJob(addJob: (Job) -> Void) throws {
186+
private mutating func addEmitModuleJob(addJobBeforeCompiles: (Job) -> Void, addJobAfterCompiles: (Job) -> Void) throws {
187187
if shouldCreateEmitModuleJob {
188-
addJob( try emitModuleJob() )
188+
let emitModuleJob = try emitModuleJob()
189+
addJobBeforeCompiles(emitModuleJob)
190+
try addVerifyJobs(emitModuleJob: emitModuleJob, addJob: addJobAfterCompiles)
189191
}
190192
}
191193

@@ -221,9 +223,11 @@ extension Driver {
221223
}
222224
}
223225

224-
try addSingleCompileJobs(addJob: addJobBeforeCompiles,
226+
if let compileJob = try addSingleCompileJobs(addJob: addJobBeforeCompiles,
225227
addJobOutputs: addJobOutputs,
226-
emitModuleTrace: loadedModuleTracePath != nil)
228+
emitModuleTrace: loadedModuleTracePath != nil) {
229+
try addVerifyJobs(emitModuleJob: compileJob, addJob: addJobAfterCompiles)
230+
}
227231

228232
try addJobsForPrimaryInputs(
229233
addCompileJobGroup: addCompileJobGroup,
@@ -239,7 +243,7 @@ extension Driver {
239243
moduleInputs: moduleInputs,
240244
moduleInputsFromJobOutputs: moduleInputsFromJobOutputs) {
241245
addJobAfterCompiles(mergeJob)
242-
try addVerifyJobs(mergeJob: mergeJob, addJob: addJobAfterCompiles)
246+
try addVerifyJobs(emitModuleJob: mergeJob, addJob: addJobAfterCompiles)
243247
try addWrapJobOrMergeOutputs(
244248
mergeJob: mergeJob,
245249
debugInfo: debugInfo,
@@ -249,13 +253,15 @@ extension Driver {
249253
return linkerInputs
250254
}
251255

256+
/// When in single compile, add one compile job and possiblity multiple backend jobs.
257+
/// Return the compile job if one was created.
252258
private mutating func addSingleCompileJobs(
253259
addJob: (Job) -> Void,
254260
addJobOutputs: ([TypedVirtualPath]) -> Void,
255261
emitModuleTrace: Bool
256-
) throws {
262+
) throws -> Job? {
257263
guard case .singleCompile = compilerMode
258-
else { return }
264+
else { return nil }
259265

260266
if parsedOptions.hasArgument(.embedBitcode),
261267
inputFiles.allSatisfy({ $0.type.isPartOfSwiftCompilation }) {
@@ -270,6 +276,7 @@ extension Driver {
270276
: nil
271277
}
272278
backendJobs.forEach(addJob)
279+
return compile
273280
} else {
274281
// We can skip the compile jobs if all we want is a module when it's
275282
// built separately.
@@ -278,6 +285,7 @@ extension Driver {
278285
addJobOutputs: addJobOutputs,
279286
emitModuleTrace: emitModuleTrace)
280287
addJob(compile)
288+
return compile
281289
}
282290
}
283291

@@ -395,7 +403,7 @@ extension Driver {
395403
return try mergeModuleJob(inputs: moduleInputs, inputsFromOutputs: moduleInputsFromJobOutputs)
396404
}
397405

398-
private mutating func addVerifyJobs(mergeJob: Job, addJob: (Job) -> Void )
406+
private mutating func addVerifyJobs(emitModuleJob: Job, addJob: (Job) -> Void )
399407
throws {
400408
guard
401409
parsedOptions.hasArgument(.enableLibraryEvolution),
@@ -413,7 +421,7 @@ extension Driver {
413421

414422
let outputType: FileType =
415423
forPrivate ? .privateSwiftInterface : .swiftInterface
416-
let mergeInterfaceOutputs = mergeJob.outputs.filter { $0.type == outputType }
424+
let mergeInterfaceOutputs = emitModuleJob.outputs.filter { $0.type == outputType }
417425
assert(mergeInterfaceOutputs.count == 1,
418426
"Merge module job should only have one swiftinterface output")
419427
let job = try verifyModuleInterfaceJob(interfaceInput: mergeInterfaceOutputs[0])

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3640,13 +3640,56 @@ final class SwiftDriverTests: XCTestCase {
36403640
XCTAssertTrue(verifyJob.outputs.isEmpty)
36413641
XCTAssertTrue(verifyJob.commandLine.contains(.path(mergeInterfaceOutputs[0].file)))
36423642
}
3643+
36433644
// No Evolution
36443645
do {
36453646
var driver = try Driver(args: ["swiftc", "foo.swift", "-emit-module", "-module-name",
36463647
"foo", "-emit-module-interface", "-verify-emitted-module-interface"])
36473648
let plannedJobs = try driver.planBuild()
36483649
XCTAssertEqual(plannedJobs.count, 2)
36493650
}
3651+
3652+
// Emit-module separately
3653+
do {
3654+
var driver = try Driver(args: ["swiftc", "foo.swift", "-emit-module", "-module-name",
3655+
"foo", "-emit-module-interface",
3656+
"-verify-emitted-module-interface",
3657+
"-enable-library-evolution",
3658+
"-experimental-emit-module-separately"])
3659+
let plannedJobs = try driver.planBuild()
3660+
XCTAssertEqual(plannedJobs.count, 2)
3661+
let emitJob = plannedJobs[0]
3662+
let verifyJob = plannedJobs[1]
3663+
XCTAssertEqual(emitJob.kind, .emitModule)
3664+
let emitInterfaceOutput = emitJob.outputs.filter { $0.type == .swiftInterface }
3665+
XCTAssertTrue(emitInterfaceOutput.count == 1,
3666+
"Emit module job should only have one swiftinterface output")
3667+
XCTAssertEqual(verifyJob.kind, .verifyModuleInterface)
3668+
XCTAssertTrue(verifyJob.inputs.count == 1)
3669+
XCTAssertTrue(verifyJob.inputs[0] == emitInterfaceOutput[0])
3670+
XCTAssertTrue(verifyJob.commandLine.contains(.path(emitInterfaceOutput[0].file)))
3671+
}
3672+
3673+
// Whole-module
3674+
do {
3675+
var driver = try Driver(args: ["swiftc", "foo.swift", "-emit-module", "-module-name",
3676+
"foo", "-emit-module-interface",
3677+
"-verify-emitted-module-interface",
3678+
"-enable-library-evolution",
3679+
"-whole-module-optimization"])
3680+
let plannedJobs = try driver.planBuild()
3681+
XCTAssertEqual(plannedJobs.count, 2)
3682+
let emitJob = plannedJobs[0]
3683+
let verifyJob = plannedJobs[1]
3684+
XCTAssertEqual(emitJob.kind, .compile)
3685+
let emitInterfaceOutput = emitJob.outputs.filter { $0.type == .swiftInterface }
3686+
XCTAssertTrue(emitInterfaceOutput.count == 1,
3687+
"Emit module job should only have one swiftinterface output")
3688+
XCTAssertEqual(verifyJob.kind, .verifyModuleInterface)
3689+
XCTAssertTrue(verifyJob.inputs.count == 1)
3690+
XCTAssertTrue(verifyJob.inputs[0] == emitInterfaceOutput[0])
3691+
XCTAssertTrue(verifyJob.commandLine.contains(.path(emitInterfaceOutput[0].file)))
3692+
}
36503693
}
36513694

36523695
func testPCHGeneration() throws {

0 commit comments

Comments
 (0)