Skip to content

Commit 0b21663

Browse files
committed
PrebuiltModuleGen: Allow arm64 interfaces to depend on arm64e interfaces
Prebuit modules of arm64e interfaces can be loaded to help building arm64 interfaces.
1 parent 1e9abfa commit 0b21663

File tree

3 files changed

+63
-9
lines changed

3 files changed

+63
-9
lines changed

Sources/SwiftDriver/Jobs/PrebuiltModulesJob.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -308,14 +308,24 @@ extension Driver {
308308
return collectSwiftModuleNames(dependencies)
309309
}
310310

311-
func getOutputPaths(for modules: [String], with arch: Triple.Arch) throws -> [TypedVirtualPath] {
311+
func getOutputPaths(withName modules: [String], loadableFor arch: Triple.Arch) throws -> [TypedVirtualPath] {
312312
var results: [TypedVirtualPath] = []
313313
modules.forEach { module in
314314
guard let allOutputs = outputMap[module] else {
315315
diagnosticEngine.emit(error: "cannot find output paths for \(module)")
316316
return
317317
}
318-
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 }
319329
results.append(contentsOf: allPaths)
320330
}
321331
return results
@@ -346,7 +356,7 @@ extension Driver {
346356
try forEachInputOutputPair(module) { input, output in
347357
jobs.append(try generateSingleModuleBuildingJob(module,
348358
prebuiltModuleDir, input, output,
349-
try getOutputPaths(for: dependencies, with: input.arch)))
359+
try getOutputPaths(withName: dependencies, loadableFor: input.arch)))
350360
}
351361
// For each dependency, add to the list to handle if the list doesn't
352362
// contain this dependency.
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)