Skip to content

Commit a152936

Browse files
committed
Move discoveredLdLinkerSpecInfo_Windows to platform tests.
* Move discoveredLdLinkerSpecInfo_Windows to the windows platform tests. * Use the helper functions to make linker tests conditional on the presence of specific host SDK components. * Update target architectures to match windows SDK.
1 parent c872bc6 commit a152936

File tree

7 files changed

+109
-79
lines changed

7 files changed

+109
-79
lines changed

Sources/SWBCore/SDKRegistry.swift

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -646,14 +646,6 @@ public final class SDKRegistry: SDKRegistryLookup, CustomStringConvertible, Send
646646
tripleEnvironment = ""
647647
}
648648

649-
let archs: PropertyListItem =
650-
switch operatingSystem {
651-
case .windows:
652-
.plArray([.plString("x86_64"), .plString("aarch64")])
653-
default:
654-
.plArray([.plString(Architecture.hostStringValue ?? "unknown")])
655-
}
656-
657649
return try [
658650
"Type": .plString("SDK"),
659651
"Version": .plString(Version(ProcessInfo.processInfo.operatingSystemVersion).zeroTrimmed.description),
@@ -664,7 +656,7 @@ public final class SDKRegistry: SDKRegistryLookup, CustomStringConvertible, Send
664656
].merging(defaultProperties, uniquingKeysWith: { _, new in new })),
665657
"SupportedTargets": .plDict([
666658
operatingSystem.xcodePlatformName: .plDict([
667-
"Archs": archs,
659+
"Archs": .plArray([.plString(Architecture.hostStringValue ?? "unknown")]),
668660
"LLVMTargetTripleEnvironment": .plString(tripleEnvironment),
669661
"LLVMTargetTripleSys": .plString(operatingSystem.xcodePlatformName),
670662
"LLVMTargetTripleVendor": .plString("unknown"),
@@ -1350,4 +1342,4 @@ private extension Array where Element == SDK {
13501342
}
13511343
return group.compactMap({ (version, sdks) -> SDK? in sdks.only }).sorted(by: { ($0.version ?? Version()) > ($1.version ?? Version()) }).first
13521344
}
1353-
}
1345+
}

Sources/SWBTestSupport/CoreBasedTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ extension CoreBasedTests {
302302
}
303303
package func linkPath(_ targetArchitecture: String) async throws -> Path? {
304304
let (core, defaultToolchain) = try await self.coreAndToolchain()
305-
let prefixMapping = [ "x86_64": "x64", "aarch64": "arm64", "i386": "x86", "thumbv7" : "arm" ]
305+
let prefixMapping = ["aarch64" : "arm64", "arm64ec" : "arm64", "armv7" : "arm", "x86_64": "x64", "i686": "x86"]
306306

307307
guard let prefix = prefixMapping[targetArchitecture] else {
308308
return nil

Sources/SWBWindowsPlatform/Plugin.swift

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import Foundation
2424

2525
public final class WindowsPlugin: Sendable {
2626
private let vsInstallations = AsyncSingleValueCache<[VSInstallation], any Error>()
27-
private let latestVsInstalltionDirectory = AsyncSingleValueCache<Path?, any Error>()
27+
private let latestVsInstallationDirectory = AsyncSingleValueCache<Path?, any Error>()
2828

2929
public func cachedVSInstallations() async throws -> [VSInstallation] {
3030
try await vsInstallations.value {
@@ -34,7 +34,7 @@ public final class WindowsPlugin: Sendable {
3434
}
3535

3636
func cachedLatestVSInstallDirectory(fs: any FSProxy) async throws -> Path? {
37-
try await latestVsInstalltionDirectory.value {
37+
try await latestVsInstallationDirectory.value {
3838
let installations = try await cachedVSInstallations()
3939
.sorted(by: { $0.installationVersion > $1.installationVersion })
4040
if let latest = installations.first {
@@ -63,29 +63,14 @@ struct WindowsPlatformSpecsExtension: SpecificationsExtension {
6363
@_spi(Testing) public func additionalEnvironmentVariables(context: any EnvironmentExtensionAdditionalEnvironmentVariablesContext) async throws -> [String: String] {
6464
if context.hostOperatingSystem == .windows {
6565
let vcToolsInstallDir = "VCToolsInstallDir"
66-
guard let dir = try? await findLatestInstallDirectory(fs: context.fs) else {
66+
guard let dir = try? await plugin.cachedLatestVSInstallDirectory(fs: context.fs) else {
6767
return [:]
6868
}
6969
return [vcToolsInstallDir: dir.str]
7070
} else {
7171
return [:]
7272
}
7373
}
74-
75-
@_spi(Testing)public func findLatestInstallDirectory(fs: any FSProxy) async throws -> Path? {
76-
let plugin: WindowsPlugin
77-
let installations = try await plugin.cachedVSInstallations()
78-
.sorted(by: { $0.installationVersion > $1.installationVersion })
79-
if let latest = installations.first {
80-
let msvcDir = latest.installationPath.join("VC").join("Tools").join("MSVC")
81-
if fs.exists(msvcDir) {
82-
let versions = try fs.listdir(msvcDir).map { try Version($0) }.sorted { $0 > $1 }
83-
if let latestVersion = versions.first {
84-
return msvcDir.join(latestVersion.description)
85-
}
86-
}
87-
}
88-
return nil
8974
}
9075

9176
struct WindowsPlatformExtension: PlatformInfoExtension {

Sources/SWBWindowsPlatform/Specs/WindowsLd.xcspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
{
6262
Name = _LD_MULTIARCH_PREFIX_MAP;
6363
Type = StringList;
64-
DefaultValue = "x86_64:x64 aarch64:arm64 i386:x86 thumbv7:arm";
64+
DefaultValue = "aarch64:arm64 armv7:arm arm64ec:arm64 x86_64:x64 i686:x86";
6565
Condition = "$(ALTERNATE_LINKER) == link";
6666
},
6767
{

Tests/SWBBuildSystemTests/LinkerTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ fileprivate struct LinkerTests: CoreBasedTests {
324324
results.checkTaskOutput(task) { output in
325325
// Expect that the 'link' linker is called by clang
326326
if runDestination == .windows && Architecture.hostStringValue == "aarch64" {
327-
// On windows aarch64 'clang' picks the wrong host architecture for link.exe, choosing "MSVC\14.41.34120\bin\Hostx86\x64\link.exe"
327+
// rdar://145868953 - On windows aarch64 'clang' picks the wrong host architecture for link.exe, choosing "MSVC\14.41.34120\bin\Hostx86\x64\link.exe"
328328
withKnownIssue("'clang' picks the wrong binary for link.exe using the Hostx86 version") {
329329
#expect(output.asString.replacingOccurrences(of: "\\\\", with: "\\").contains(linkLinkerPathX86.str))
330330
}
@@ -344,7 +344,7 @@ fileprivate struct LinkerTests: CoreBasedTests {
344344
results.checkTaskOutput(task) { output in
345345
// Expect that the 'link' linker is called by clang
346346
if runDestination == .windows && Architecture.hostStringValue == "aarch64" {
347-
// On windows aarch64 'clang' picks the wrong host architecture for link.exe, choosing "MSVC\14.41.34120\bin\Hostx86\x64\link.exe"
347+
// rdar://145868953 - On windows aarch64 'clang' picks the wrong host architecture for link.exe, choosing "MSVC\14.41.34120\bin\Hostx86\x64\link.exe"
348348
withKnownIssue("'clang' picks the wrong binary for link.exe using the Hostx86 version") {
349349
#expect(output.asString.replacingOccurrences(of: "\\\\", with: "\\").contains(linkLinkerPathAarch64.str))
350350
}

Tests/SWBCoreTests/CommandLineToolSpecDiscoveredInfoTests.swift

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -234,53 +234,6 @@ import SWBMacro
234234
}
235235
}
236236

237-
@Test(.requireSDKs(.windows))
238-
func discoveredLdLinkerSpecInfo_Windows() async throws {
239-
var table = try await ldMacroTable()
240-
table.push(BuiltinMacros._LD_MULTIARCH, literal: true)
241-
try await withSpec(LdLinkerSpec.self, .deferred, platform: "windows", additionalTable: table) { (info: DiscoveredLdLinkerToolSpecInfo) in
242-
#expect(!info.toolPath.isEmpty)
243-
#expect(info.toolVersion != nil)
244-
if let toolVersion = info.toolVersion {
245-
#expect(toolVersion > Version(0, 0, 0))
246-
}
247-
#expect(info.linker == .lld)
248-
}
249-
try await withSpec(LdLinkerSpec.self, .result(status: .exit(0), stdout: Data("Microsoft (R) Incremental Linker Version 14.41.34120.0\n".utf8), stderr: Data()), platform: "windows", additionalTable: table) { (info: DiscoveredLdLinkerToolSpecInfo) in
250-
#expect(!info.toolPath.isEmpty)
251-
#expect(info.toolVersion == Version(14, 41, 34120))
252-
#expect(info.architectures == Set())
253-
}
254-
255-
// link.exe cannot be used for multipler architectures and requires a distinct link.exe for each target architecture
256-
table.push(BuiltinMacros.ALTERNATE_LINKER, literal: "link")
257-
table.push(BuiltinMacros._LD_MULTIARCH, literal: false)
258-
table.push(BuiltinMacros._LD_MULTIARCH_PREFIX_MAP, literal: ["x86_64:x64", "aarch64:arm64", "i386:x86", "thumbv7:arm"])
259-
260-
// x86_64
261-
table.push(BuiltinMacros.ARCHS, literal: ["x86_64"])
262-
try await withSpec(LdLinkerSpec.self, .deferred, platform: "windows", additionalTable: table) { (info: DiscoveredLdLinkerToolSpecInfo) in
263-
#expect(!info.toolPath.isEmpty)
264-
#expect(info.toolVersion != nil)
265-
if let toolVersion = info.toolVersion {
266-
#expect(toolVersion > Version(0, 0, 0))
267-
}
268-
#expect(info.linker == .linkExe)
269-
}
270-
271-
// FIXME: Fails in swift-ci missing arm64 toolchain on x86_64 host.
272-
// // link aarch64
273-
// table.push(BuiltinMacros.ARCHS, literal: ["aarch64"])
274-
// try await withSpec(LdLinkerSpec.self, .deferred, platform: "windows", additionalTable: table) { (info: DiscoveredLdLinkerToolSpecInfo) in
275-
// #expect(!info.toolPath.isEmpty)
276-
// #expect(info.toolVersion != nil)
277-
// if let toolVersion = info.toolVersion {
278-
// #expect(toolVersion > Version(0, 0, 0))
279-
// }
280-
// #expect(info.linker == .linkExe)
281-
// }
282-
}
283-
284237
@Test(.skipHostOS(.windows), .requireSystemPackages(apt: "libtool", yum: "libtool"))
285238
func discoveredLibtoolSpecInfo() async throws {
286239
try await withSpec(LibtoolLinkerSpec.self, .deferred) { (info: DiscoveredLibtoolLinkerToolSpecInfo) in

Tests/SWBWindowsPlatformTests/SWBWindowsPlatformTests.swift

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,104 @@
99
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12+
import Foundation
13+
@_spi(Testing) import SWBCore
14+
import SWBProtocol
15+
import SWBTestSupport
16+
import SWBUtil
17+
import Testing
18+
import SWBMacro
1219

20+
@Suite fileprivate struct CommandLineToolSpecDiscoveredInfoTests: CoreBasedTests {
21+
// Linker tool discovery is a bit more complex as it afffected by the ALTERNATE_LINKER build setting.
22+
func ldMacroTable() async throws -> MacroValueAssignmentTable {
23+
let core = try await getCore()
24+
return MacroValueAssignmentTable(namespace: core.specRegistry.internalMacroNamespace)
25+
}
26+
27+
@Test(.requireSDKs(.windows))
28+
func discoveredLdLinkerSpecInfo_Windows() async throws {
29+
var table = try await ldMacroTable()
30+
let core = try await getCore()
31+
table.push(BuiltinMacros._LD_MULTIARCH, literal: true)
32+
try await withSpec(LdLinkerSpec.self, .deferred, platform: "windows", additionalTable: table) { (info: DiscoveredLdLinkerToolSpecInfo) in
33+
#expect(!info.toolPath.isEmpty)
34+
#expect(info.toolVersion != nil)
35+
if let toolVersion = info.toolVersion {
36+
#expect(toolVersion > Version(0, 0, 0))
37+
}
38+
#expect(info.linker == .lld)
39+
}
40+
try await withSpec(LdLinkerSpec.self, .result(status: .exit(0), stdout: Data("Microsoft (R) Incremental Linker Version 14.41.34120.0\n".utf8), stderr: Data()), platform: "windows", additionalTable: table) { (info: DiscoveredLdLinkerToolSpecInfo) in
41+
#expect(!info.toolPath.isEmpty)
42+
#expect(info.toolVersion == Version(14, 41, 34120))
43+
#expect(info.architectures == Set())
44+
}
45+
46+
// link.exe cannot be used for multipler architectures and requires a distinct link.exe for each target architecture
47+
table.push(BuiltinMacros.ALTERNATE_LINKER, literal: "link")
48+
table.push(BuiltinMacros._LD_MULTIARCH, literal: false)
49+
table.push(BuiltinMacros._LD_MULTIARCH_PREFIX_MAP, literal: ["aarch64:arm64", "arm64ec:arm64", "armv7:arm", "x86_64:x64", "i686:x86"])
50+
51+
// link x86_64
52+
if try await core.hasVisualStudioComponent(.visualCppBuildTools_x86_x64) {
53+
table.push(BuiltinMacros.ARCHS, literal: ["x86_64"])
54+
try await withSpec(LdLinkerSpec.self, .deferred, platform: "windows", additionalTable: table) { (info: DiscoveredLdLinkerToolSpecInfo) in
55+
#expect(!info.toolPath.isEmpty)
56+
#expect(info.toolVersion != nil)
57+
if let toolVersion = info.toolVersion {
58+
#expect(toolVersion > Version(0, 0, 0))
59+
}
60+
#expect(info.linker == .linkExe)
61+
}
62+
}
63+
// link i686
64+
if try await core.hasVisualStudioComponent(.visualCppBuildTools_x86_x64) {
65+
table.push(BuiltinMacros.ARCHS, literal: ["i686"])
66+
try await withSpec(LdLinkerSpec.self, .deferred, platform: "windows", additionalTable: table) { (info: DiscoveredLdLinkerToolSpecInfo) in
67+
#expect(!info.toolPath.isEmpty)
68+
#expect(info.toolVersion != nil)
69+
if let toolVersion = info.toolVersion {
70+
#expect(toolVersion > Version(0, 0, 0))
71+
}
72+
#expect(info.linker == .linkExe)
73+
}
74+
}
75+
// link aarch64
76+
if try await core.hasVisualStudioComponent(.visualCppBuildTools_arm64) {
77+
table.push(BuiltinMacros.ARCHS, literal: ["aarch64"])
78+
try await withSpec(LdLinkerSpec.self, .deferred, platform: "windows", additionalTable: table) { (info: DiscoveredLdLinkerToolSpecInfo) in
79+
#expect(!info.toolPath.isEmpty)
80+
#expect(info.toolVersion != nil)
81+
if let toolVersion = info.toolVersion {
82+
#expect(toolVersion > Version(0, 0, 0))
83+
}
84+
#expect(info.linker == .linkExe)
85+
}
86+
}
87+
// link armv7
88+
if try await core.hasVisualStudioComponent(.visualCppBuildTools_arm) {
89+
table.push(BuiltinMacros.ARCHS, literal: ["armv7"])
90+
try await withSpec(LdLinkerSpec.self, .deferred, platform: "windows", additionalTable: table) { (info: DiscoveredLdLinkerToolSpecInfo) in
91+
#expect(!info.toolPath.isEmpty)
92+
#expect(info.toolVersion != nil)
93+
if let toolVersion = info.toolVersion {
94+
#expect(toolVersion > Version(0, 0, 0))
95+
}
96+
#expect(info.linker == .linkExe)
97+
}
98+
}
99+
// link arm64ec
100+
if try await core.hasVisualStudioComponent(.visualCppBuildTools_arm64ec) {
101+
table.push(BuiltinMacros.ARCHS, literal: ["arm64ec"])
102+
try await withSpec(LdLinkerSpec.self, .deferred, platform: "windows", additionalTable: table) { (info: DiscoveredLdLinkerToolSpecInfo) in
103+
#expect(!info.toolPath.isEmpty)
104+
#expect(info.toolVersion != nil)
105+
if let toolVersion = info.toolVersion {
106+
#expect(toolVersion > Version(0, 0, 0))
107+
}
108+
#expect(info.linker == .linkExe)
109+
}
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)