Skip to content

Commit 40a45ec

Browse files
Merge pull request #1308 from cachemeifyoucan/eng/PR-106430264
Compute and reuse bridging header pch explicitly in explicit module b…
2 parents edea61b + 24c28c9 commit 40a45ec

File tree

3 files changed

+140
-2
lines changed

3 files changed

+140
-2
lines changed

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

+6-1
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,12 @@ extension Driver {
343343
commandLine.appendFlag(.importObjcHeader)
344344
if bridgingHeaderHandling == .precompiled,
345345
let pch = bridgingPrecompiledHeader {
346-
if parsedOptions.contains(.pchOutputDir) {
346+
// For explicit module build, we directly pass the compiled pch as
347+
// `-import-objc-header`, rather than rely on swift-frontend to locate
348+
// the pch in the pchOutputDir and can start an implicit build in case
349+
// of a lookup failure.
350+
if parsedOptions.contains(.pchOutputDir) &&
351+
!parsedOptions.contains(.driverExplicitModuleBuild) {
347352
commandLine.appendPath(VirtualPath.lookup(importedObjCHeader))
348353
try commandLine.appendLast(.pchOutputDir, from: &parsedOptions)
349354
if !compilerMode.isSingleCompilation {

Sources/SwiftDriver/Jobs/GeneratePCHJob.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ extension Driver {
5353

5454
commandLine.appendFlag(.emitPch)
5555

56-
if parsedOptions.hasArgument(.pchOutputDir) {
56+
if parsedOptions.hasArgument(.pchOutputDir) &&
57+
!parsedOptions.contains(.driverExplicitModuleBuild) {
5758
try commandLine.appendLast(.pchOutputDir, from: &parsedOptions)
5859
} else {
5960
commandLine.appendFlag(.o)

Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift

+132
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,138 @@ final class ExplicitModuleBuildTests: XCTestCase {
374374
}
375375
}
376376

377+
/// Test generation of explicit module build jobs for dependency modules when the driver
378+
/// is invoked with -explicit-module-build and -pch-output-dir
379+
func testExplicitModuleBuildPCHOutputJobs() throws {
380+
try withTemporaryDirectory { path in
381+
let main = path.appending(component: "testExplicitModuleBuildPCHOutputJobs.swift")
382+
try localFileSystem.writeFileContents(main) {
383+
$0 <<< "import C;"
384+
$0 <<< "import E;"
385+
$0 <<< "import G;"
386+
}
387+
388+
let cHeadersPath: AbsolutePath =
389+
testInputsPath.appending(component: "ExplicitModuleBuilds")
390+
.appending(component: "CHeaders")
391+
let bridgingHeaderpath: AbsolutePath =
392+
cHeadersPath.appending(component: "Bridging.h")
393+
let swiftModuleInterfacesPath: AbsolutePath =
394+
testInputsPath.appending(component: "ExplicitModuleBuilds")
395+
.appending(component: "Swift")
396+
let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? []
397+
let pchOutputDir: AbsolutePath = path
398+
var driver = try Driver(args: ["swiftc",
399+
"-target", "x86_64-apple-macosx11.0",
400+
"-I", cHeadersPath.nativePathString(escaped: true),
401+
"-I", swiftModuleInterfacesPath.nativePathString(escaped: true),
402+
"-explicit-module-build",
403+
"-import-objc-header", bridgingHeaderpath.nativePathString(escaped: true),
404+
"-pch-output-dir", pchOutputDir.nativePathString(escaped: true),
405+
main.nativePathString(escaped: true)] + sdkArgumentsForTesting)
406+
407+
let jobs = try driver.planBuild()
408+
// Figure out which Triples to use.
409+
let dependencyGraph = try driver.gatherModuleDependencies()
410+
let mainModuleInfo = try dependencyGraph.moduleInfo(of: .swift("testExplicitModuleBuildPCHOutputJobs"))
411+
guard case .swift(_) = mainModuleInfo.details else {
412+
XCTFail("Main module does not have Swift details field")
413+
return
414+
}
415+
416+
for job in jobs {
417+
XCTAssertEqual(job.outputs.count, 1)
418+
let outputFilePath = job.outputs[0].file
419+
420+
// Swift dependencies
421+
if outputFilePath.extension != nil,
422+
outputFilePath.extension! == FileType.swiftModule.rawValue {
423+
if pathMatchesSwiftModule(path: outputFilePath, "A") {
424+
try checkExplicitModuleBuildJob(job: job, moduleId: .swift("A"),
425+
dependencyGraph: dependencyGraph)
426+
} else if pathMatchesSwiftModule(path: outputFilePath, "E") {
427+
try checkExplicitModuleBuildJob(job: job, moduleId: .swift("E"),
428+
dependencyGraph: dependencyGraph)
429+
} else if pathMatchesSwiftModule(path: outputFilePath, "G") {
430+
try checkExplicitModuleBuildJob(job: job, moduleId: .swift("G"),
431+
dependencyGraph: dependencyGraph)
432+
} else if pathMatchesSwiftModule(path: outputFilePath, "Swift") {
433+
try checkExplicitModuleBuildJob(job: job, moduleId: .swift("Swift"),
434+
dependencyGraph: dependencyGraph)
435+
} else if pathMatchesSwiftModule(path: outputFilePath, "_Concurrency") {
436+
try checkExplicitModuleBuildJob(job: job, moduleId: .swift("_Concurrency"),
437+
dependencyGraph: dependencyGraph)
438+
} else if pathMatchesSwiftModule(path: outputFilePath, "_StringProcessing") {
439+
try checkExplicitModuleBuildJob(job: job, moduleId: .swift("_StringProcessing"),
440+
dependencyGraph: dependencyGraph)
441+
} else if pathMatchesSwiftModule(path: outputFilePath, "SwiftOnoneSupport") {
442+
try checkExplicitModuleBuildJob(job: job, moduleId: .swift("SwiftOnoneSupport"),
443+
dependencyGraph: dependencyGraph)
444+
}
445+
// Clang Dependencies
446+
} else if let outputExtension = outputFilePath.extension,
447+
outputExtension == FileType.pcm.rawValue {
448+
let relativeOutputPathFileName = outputFilePath.basename
449+
if relativeOutputPathFileName.starts(with: "A-") {
450+
try checkExplicitModuleBuildJob(job: job, moduleId: .clang("A"),
451+
dependencyGraph: dependencyGraph)
452+
}
453+
else if relativeOutputPathFileName.starts(with: "B-") {
454+
try checkExplicitModuleBuildJob(job: job, moduleId: .clang("B"),
455+
dependencyGraph: dependencyGraph)
456+
}
457+
else if relativeOutputPathFileName.starts(with: "C-") {
458+
try checkExplicitModuleBuildJob(job: job, moduleId: .clang("C"),
459+
dependencyGraph: dependencyGraph)
460+
}
461+
else if relativeOutputPathFileName.starts(with: "G-") {
462+
try checkExplicitModuleBuildJob(job: job, moduleId: .clang("G"),
463+
dependencyGraph: dependencyGraph)
464+
}
465+
else if relativeOutputPathFileName.starts(with: "F-") {
466+
try checkExplicitModuleBuildJob(job: job, moduleId: .clang("F"),
467+
dependencyGraph: dependencyGraph)
468+
}
469+
else if relativeOutputPathFileName.starts(with: "SwiftShims-") {
470+
try checkExplicitModuleBuildJob(job: job, moduleId: .clang("SwiftShims"),
471+
dependencyGraph: dependencyGraph)
472+
}
473+
else if relativeOutputPathFileName.starts(with: "_SwiftConcurrencyShims-") {
474+
try checkExplicitModuleBuildJob(job: job, moduleId: .clang("_SwiftConcurrencyShims"),
475+
dependencyGraph: dependencyGraph)
476+
}
477+
else {
478+
XCTFail("Unexpected module dependency build job output: \(outputFilePath)")
479+
}
480+
// Bridging header
481+
} else if let outputExtension = outputFilePath.extension,
482+
outputExtension == FileType.pch.rawValue {
483+
switch (outputFilePath) {
484+
case .absolute:
485+
// pch output is a computed absolute path.
486+
XCTAssertFalse(job.commandLine.contains("-pch-output-dir"))
487+
default:
488+
XCTFail("Unexpected module dependency build job output: \(outputFilePath)")
489+
}
490+
} else {
491+
// Check we don't use `-pch-output-dir` anymore during main module job.
492+
XCTAssertFalse(job.commandLine.contains("-pch-output-dir"))
493+
switch (outputFilePath) {
494+
case .relative(RelativePath("testExplicitModuleBuildPCHOutputJobs")):
495+
XCTAssertTrue(driver.isExplicitMainModuleJob(job: job))
496+
XCTAssertEqual(job.kind, .link)
497+
case .temporary(_):
498+
let baseName = "testExplicitModuleBuildPCHOutputJobs"
499+
XCTAssertTrue(matchTemporary(outputFilePath, basename: baseName, fileExtension: "o") ||
500+
matchTemporary(outputFilePath, basename: baseName, fileExtension: "autolink"))
501+
default:
502+
XCTFail("Unexpected module dependency build job output: \(outputFilePath)")
503+
}
504+
}
505+
}
506+
}
507+
}
508+
377509
func testImmediateModeExplicitModuleBuild() throws {
378510
try withTemporaryDirectory { path in
379511
let main = path.appending(component: "testExplicitModuleBuildJobs.swift")

0 commit comments

Comments
 (0)