Skip to content

Commit 7864f83

Browse files
authored
Merge pull request #597 from nkcsgexi/verbose
PrebuiltModuleGen: Allow arm64 interfaces to depend on arm64e interfaces
2 parents ff622c2 + 0b21663 commit 7864f83

File tree

4 files changed

+129
-41
lines changed

4 files changed

+129
-41
lines changed

Sources/SwiftDriver/Jobs/PrebuiltModulesJob.swift

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,69 @@
1212
import TSCBasic
1313
import SwiftOptions
1414

15+
public class PrebuitModuleGenerationDelegate: JobExecutionDelegate {
16+
var failingModules = Set<String>()
17+
var commandMap: [Int: String] = [:]
18+
let diagnosticsEngine: DiagnosticsEngine
19+
let verbose: Bool
20+
public init(_ diagnosticsEngine: DiagnosticsEngine, _ verbose: Bool) {
21+
self.diagnosticsEngine = diagnosticsEngine
22+
self.verbose = verbose
23+
}
24+
25+
func printJobInfo(_ job: Job, _ start: Bool) {
26+
guard verbose else {
27+
return
28+
}
29+
for arg in job.commandLine {
30+
if case .path(let p) = arg {
31+
if p.extension == "swiftinterface" {
32+
Driver.stdErrQueue.sync {
33+
stderrStream <<< (start ? "started: " : "finished: ")
34+
stderrStream <<< p.absolutePath!.pathString <<< "\n"
35+
stderrStream.flush()
36+
}
37+
return
38+
}
39+
}
40+
}
41+
}
42+
43+
public func jobStarted(job: Job, arguments: [String], pid: Int) {
44+
commandMap[pid] = arguments.reduce("") { return $0 + " " + $1 }
45+
printJobInfo(job, true)
46+
}
47+
48+
public var hasStdlibFailure: Bool {
49+
return failingModules.contains("Swift") || failingModules.contains("_Concurrency")
50+
}
51+
52+
public func jobFinished(job: Job, result: ProcessResult, pid: Int) {
53+
switch result.exitStatus {
54+
case .terminated(code: let code):
55+
if code == 0 {
56+
printJobInfo(job, false)
57+
} else {
58+
failingModules.insert(job.moduleName)
59+
let result: String = try! result.utf8stderrOutput()
60+
Driver.stdErrQueue.sync {
61+
stderrStream <<< "failed: " <<< commandMap[pid]! <<< "\n"
62+
stderrStream <<< result <<< "\n"
63+
stderrStream.flush()
64+
}
65+
}
66+
#if !os(Windows)
67+
case .signalled:
68+
diagnosticsEngine.emit(.remark("\(job.moduleName) interrupted"))
69+
#endif
70+
}
71+
}
72+
73+
public func jobSkipped(job: Job) {
74+
diagnosticsEngine.emit(.error("\(job.moduleName) skipped"))
75+
}
76+
}
77+
1578
public struct PrebuiltModuleInput {
1679
// The path to the input/output of the a module building task.
1780
let path: TypedVirtualPath
@@ -245,14 +308,24 @@ extension Driver {
245308
return collectSwiftModuleNames(dependencies)
246309
}
247310

248-
func getOutputPaths(for modules: [String], with arch: Triple.Arch) throws -> [TypedVirtualPath] {
311+
func getOutputPaths(withName modules: [String], loadableFor arch: Triple.Arch) throws -> [TypedVirtualPath] {
249312
var results: [TypedVirtualPath] = []
250313
modules.forEach { module in
251314
guard let allOutputs = outputMap[module] else {
252315
diagnosticEngine.emit(error: "cannot find output paths for \(module)")
253316
return
254317
}
255-
let allPaths = allOutputs.filter { $0.arch == arch }.map { $0.path }
318+
let allPaths = allOutputs.filter { output in
319+
if output.arch == arch {
320+
return true
321+
}
322+
// arm64e interfaces can be loded from an arm64 interface but not vice
323+
// versa.
324+
if arch == .aarch64 && output.arch == .aarch64e {
325+
return true
326+
}
327+
return false
328+
}.map { $0.path }
256329
results.append(contentsOf: allPaths)
257330
}
258331
return results
@@ -283,7 +356,7 @@ extension Driver {
283356
try forEachInputOutputPair(module) { input, output in
284357
jobs.append(try generateSingleModuleBuildingJob(module,
285358
prebuiltModuleDir, input, output,
286-
try getOutputPaths(for: dependencies, with: input.arch)))
359+
try getOutputPaths(withName: dependencies, loadableFor: input.arch)))
287360
}
288361
// For each dependency, add to the list to handle if the list doesn't
289362
// contain this dependency.

Sources/swift-build-sdk-interfaces/main.swift

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -38,38 +38,9 @@ if rawOutputDir.isEmpty {
3838
/// they are Foundation and anything below.
3939
let coreMode = CommandLine.arguments.contains("-core")
4040

41-
class PrebuitGenDelegate: JobExecutionDelegate {
42-
var failingModules = Set<String>()
43-
var commandMap: [Int: String] = [:]
44-
func jobStarted(job: Job, arguments: [String], pid: Int) {
45-
commandMap[pid] = arguments.reduce("") { return $0 + " " + $1 }
46-
}
47-
48-
var hasStdlibFailure: Bool {
49-
return failingModules.contains("Swift") || failingModules.contains("_Concurrency")
50-
}
41+
/// Verbose to print more info
42+
let verbose = CommandLine.arguments.contains("-v")
5143

52-
func jobFinished(job: Job, result: ProcessResult, pid: Int) {
53-
switch result.exitStatus {
54-
case .terminated(code: let code):
55-
if code != 0 {
56-
failingModules.insert(job.moduleName)
57-
Driver.stdErrQueue.sync {
58-
stderrStream <<< "failed: " <<< commandMap[pid]! <<< "\n"
59-
stderrStream.flush()
60-
}
61-
}
62-
#if !os(Windows)
63-
case .signalled:
64-
diagnosticsEngine.emit(.remark("\(job.moduleName) interrupted"))
65-
#endif
66-
}
67-
}
68-
69-
func jobSkipped(job: Job) {
70-
diagnosticsEngine.emit(.error("\(job.moduleName) skipped"))
71-
}
72-
}
7344
do {
7445
let sdkPath = try VirtualPath(path: sdkPathRaw).absolutePath!
7546
if !localFileSystem.exists(sdkPath) {
@@ -136,7 +107,7 @@ do {
136107
executor: executor,
137108
compilerExecutableDir: swiftcPath.parentDirectory)
138109
let (jobs, danglingJobs) = try driver.generatePrebuitModuleGenerationJobs(with: inputMap, into: outputDir, exhaustive: !coreMode)
139-
let delegate = PrebuitGenDelegate()
110+
let delegate = PrebuitModuleGenerationDelegate(diagnosticsEngine, verbose)
140111
do {
141112
try executor.execute(workload: DriverExecutorWorkload.init(jobs, nil, continueBuildingAfterErrors: true),
142113
delegate: delegate, numParallelJobs: 128)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-module-flags: -module-name F
3+
import Swift
4+
import A
5+
public func FuncF() { }
6+

Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -766,11 +766,26 @@ final class ExplicitModuleBuildTests: XCTestCase {
766766
}
767767

768768
func checkInputOutputIntegrity(_ job: Job) {
769-
let name = job.outputs[0].file.basename
769+
let name = job.outputs[0].file.basenameWithoutExt
770+
XCTAssertTrue(job.outputs[0].file.extension == "swiftmodule")
770771
job.inputs.forEach { input in
771-
XCTAssertTrue(input.file.basename == name)
772+
XCTAssertTrue(input.file.extension == "swiftmodule")
773+
let inputName = input.file.basenameWithoutExt
774+
// arm64 interface can depend on ar64e interface
775+
if inputName.starts(with: "arm64e-") && name.starts(with: "arm64-") {
776+
return
777+
}
778+
XCTAssertTrue(inputName == name)
779+
}
780+
}
781+
782+
func findJob(_ jobs: [Job],_ module: String, _ basenameWithoutExt: String) -> Job? {
783+
return jobs.first { job in
784+
return job.moduleName == module &&
785+
job.outputs[0].file.basenameWithoutExt == basenameWithoutExt
772786
}
773787
}
788+
774789
let packageRootPath = URL(fileURLWithPath: #file).pathComponents
775790
.prefix(while: { $0 != "Tests" }).joined(separator: "/").dropFirst()
776791
let testInputsPath = packageRootPath + "/TestInputs"
@@ -783,7 +798,7 @@ final class ExplicitModuleBuildTests: XCTestCase {
783798
XCTAssertTrue(interfaceMap["Swift"]!.count == 2)
784799
XCTAssertTrue(interfaceMap["A"]!.count == 2)
785800
XCTAssertTrue(interfaceMap["E"]!.count == 2)
786-
XCTAssertTrue(interfaceMap["F"]!.count == 2)
801+
XCTAssertTrue(interfaceMap["F"]!.count == 3)
787802
XCTAssertTrue(interfaceMap["G"]!.count == 2)
788803
XCTAssertTrue(interfaceMap["H"]!.count == 2)
789804

@@ -809,7 +824,7 @@ final class ExplicitModuleBuildTests: XCTestCase {
809824
XCTAssertTrue(danglingJobs.allSatisfy { job in
810825
job.moduleName == "MissingKit"
811826
})
812-
XCTAssertTrue(jobs.count == 12)
827+
XCTAssertTrue(jobs.count == 13)
813828
XCTAssertTrue(jobs.allSatisfy {$0.outputs.count == 1})
814829
XCTAssertTrue(jobs.allSatisfy {$0.kind == .compile})
815830
XCTAssertTrue(jobs.allSatisfy {$0.commandLine.contains(.flag("-compile-module-from-interface"))})
@@ -842,7 +857,7 @@ final class ExplicitModuleBuildTests: XCTestCase {
842857
exhaustive: false)
843858

844859
XCTAssertTrue(danglingJobs.isEmpty)
845-
XCTAssertTrue(jobs.count == 12)
860+
XCTAssertTrue(jobs.count == 13)
846861
XCTAssertTrue(jobs.allSatisfy {$0.outputs.count == 1})
847862
XCTAssertTrue(jobs.allSatisfy {$0.kind == .compile})
848863
XCTAssertTrue(jobs.allSatisfy {$0.commandLine.contains(.flag("-compile-module-from-interface"))})
@@ -892,13 +907,36 @@ final class ExplicitModuleBuildTests: XCTestCase {
892907
exhaustive: false)
893908

894909
XCTAssertTrue(danglingJobs.isEmpty)
895-
XCTAssertTrue(jobs.count == 6)
910+
XCTAssertTrue(jobs.count == 7)
896911
jobs.forEach({ job in
897912
// Check we don't pull in other modules than A, F and Swift
898913
XCTAssertTrue(["A", "F", "Swift"].contains(job.moduleName))
899914
checkInputOutputIntegrity(job)
900915
})
901916
}
917+
try withTemporaryDirectory { path in
918+
let main = path.appending(component: "testPrebuiltModuleGenerationJobs.swift")
919+
try localFileSystem.writeFileContents(main) {
920+
$0 <<< "import H\n"
921+
}
922+
var driver = try Driver(args: ["swiftc", main.pathString,
923+
"-sdk", mockSDKPath,
924+
])
925+
926+
let (jobs, _) = try driver.generatePrebuitModuleGenerationJobs(with: interfaceMap,
927+
into: VirtualPath(path: "/tmp/").absolutePath!,
928+
exhaustive: false)
929+
let F = findJob(jobs, "F", "arm64-apple-macos")!
930+
let H = findJob(jobs, "H", "arm64e-apple-macos")!
931+
// Test arm64 interface requires arm64e interfaces as inputs
932+
XCTAssertTrue(F.inputs.contains { input in
933+
input.file.basenameWithoutExt == "arm64e-apple-macos"
934+
})
935+
// Test arm64e interface doesn't require arm64 interfaces as inputs
936+
XCTAssertTrue(!H.inputs.contains { input in
937+
input.file.basenameWithoutExt == "arm64-apple-macos"
938+
})
939+
}
902940
}
903941
#endif
904942
}

0 commit comments

Comments
 (0)