Skip to content

Commit 6fa715f

Browse files
committed
Fix backward compatibility in host triple checks (#6819)
When setting host triple in Swift SDKs to `arm64-apple-macosx13.0` to allow cross-compiling from an older version of macOS, this triple is not recognized as directly matching `arm64-apple-macosx14.0` on a newer version of macOS. We should support backward compatibility with Swift SDKs that were built for older version of macOS. Resolves rdar://113967401.
1 parent 434598e commit 6fa715f

File tree

4 files changed

+103
-41
lines changed

4 files changed

+103
-41
lines changed

Sources/Basics/Triple+Basics.swift

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -184,22 +184,18 @@ extension Triple {
184184
}
185185
}
186186

187-
public func isRuntimeCompatible(with triple: Triple) -> Bool {
187+
/// Returns `true` if code compiled for `triple` can run on `self` value of ``Triple``.
188+
public func isRuntimeCompatible(with triple: Triple) -> Bool {
188189
guard self != triple else {
189190
return true
190191
}
191-
192192
if
193193
self.arch == triple.arch &&
194194
self.vendor == triple.vendor &&
195195
self.os == triple.os &&
196-
self.environment == triple.environment,
197-
// If either of the triples have no `osVersion` specified, we can't determine compatibility and will
198-
// have to return `false`.
199-
let selfOSVersion = self.osVersion,
200-
let osVersion = triple.osVersion
196+
self.environment == triple.environment
201197
{
202-
return selfOSVersion >= osVersion
198+
return self.osVersion >= triple.osVersion
203199
} else {
204200
return false
205201
}

Sources/PackageModel/SwiftSDKBundle.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public struct SwiftSDKBundle {
8585
guard let swiftSDKsDirectory else {
8686
throw StringError(
8787
"""
88-
No directory found for installed Swift SDKs, specify one
88+
No directory found for installed Swift SDKs, specify one \
8989
with `--experimental-swift-sdks-path` option.
9090
"""
9191
)
@@ -110,8 +110,8 @@ public struct SwiftSDKBundle {
110110
) else {
111111
throw StringError(
112112
"""
113-
No Swift SDK found matching query `\(selector)` and host triple
114-
`\(hostTriple.tripleString)`. Use `swift experimental-sdk list` command to see
113+
No Swift SDK found matching query `\(selector)` and host triple \
114+
`\(hostTriple.tripleString)`. Use `swift experimental-sdk list` command to see \
115115
available Swift SDKs.
116116
"""
117117
)

Tests/BasicsTests/TripleTests.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,11 @@ final class TripleTests: XCTestCase {
220220
try XCTAssertFalse(Triple("x86_64-apple-macosx").isRuntimeCompatible(with: Triple("x86_64-apple-linux")))
221221
try XCTAssertTrue(Triple("x86_64-apple-macosx14.0").isRuntimeCompatible(with: Triple("x86_64-apple-macosx13.0")))
222222
}
223+
224+
func testIsRuntimeCompatibleWith() throws {
225+
try XCTAssertTrue(Triple("x86_64-apple-macosx").isRuntimeCompatible(with: Triple("x86_64-apple-macosx")))
226+
try XCTAssertTrue(Triple("x86_64-unknown-linux").isRuntimeCompatible(with: Triple("x86_64-unknown-linux")))
227+
try XCTAssertFalse(Triple("x86_64-apple-macosx").isRuntimeCompatible(with: Triple("x86_64-apple-linux")))
228+
try XCTAssertTrue(Triple("x86_64-apple-macosx14.0").isRuntimeCompatible(with: Triple("x86_64-apple-macosx13.0")))
229+
}
223230
}

Tests/PackageModelTests/SwiftSDKBundleTests.swift

Lines changed: 89 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import Basics
14-
import PackageModel
14+
@testable import PackageModel
1515
import SPMTestSupport
1616
import XCTest
1717

@@ -21,27 +21,58 @@ import class TSCBasic.InMemoryFileSystem
2121

2222
private let testArtifactID = "test-artifact"
2323

24-
private func generateInfoJSON(artifacts: [MockArtifact]) -> SerializedJSON {
25-
"""
26-
{
27-
"artifacts" : {
28-
\(artifacts.map {
29-
"""
30-
"\($0.id)" : {
31-
"type" : "swiftSDK",
32-
"version" : "0.0.1",
33-
"variants" : [
34-
{
35-
"path" : "\($0.id)/aarch64-unknown-linux",
36-
"supportedTriples" : \($0.supportedTriples.map(\.tripleString))
24+
private let targetTriple = try! Triple("aarch64-unknown-linux")
25+
26+
private let jsonEncoder = JSONEncoder()
27+
28+
private func generateBundleFiles(bundle: MockBundle) throws -> [(String, ByteString)] {
29+
try [
30+
(
31+
"\(bundle.path)/info.json",
32+
ByteString(json: """
33+
{
34+
"artifacts" : {
35+
\(bundle.artifacts.map {
36+
"""
37+
"\($0.id)" : {
38+
"type" : "swiftSDK",
39+
"version" : "0.0.1",
40+
"variants" : [
41+
{
42+
"path" : "\($0.id)/\(targetTriple.triple)",
43+
"supportedTriples" : \($0.supportedTriples.map(\.tripleString))
44+
}
45+
]
3746
}
38-
]
39-
}
40-
"""
41-
}.joined(separator: ",\n")
42-
)
43-
},
44-
"schemaVersion" : "1.0"
47+
"""
48+
}.joined(separator: ",\n")
49+
)
50+
},
51+
"schemaVersion" : "1.0"
52+
}
53+
""")
54+
),
55+
56+
] + bundle.artifacts.map {
57+
(
58+
"\(bundle.path)/\($0.id)/\(targetTriple.tripleString)/swift-sdk.json",
59+
ByteString(json: try generateSwiftSDKMetadata(jsonEncoder))
60+
)
61+
}
62+
}
63+
64+
private func generateSwiftSDKMetadata(_ encoder: JSONEncoder) throws -> SerializedJSON {
65+
try """
66+
{
67+
"schemaVersion": "4.0",
68+
"targetTriples": \(
69+
String(
70+
bytes: encoder.encode([
71+
targetTriple.tripleString: SwiftSDKMetadataV4.TripleProperties(sdkRootPath: "sdk")
72+
]),
73+
encoding: .utf8
74+
)!
75+
)
4576
}
4677
"""
4778
}
@@ -63,15 +94,13 @@ private func generateTestFileSystem(bundleArtifacts: [MockArtifact]) throws -> (
6394
return MockBundle(name: "test\(i).artifactbundle", path: "/\(bundleName)", artifacts: [artifacts])
6495
}
6596

66-
let fileSystem = InMemoryFileSystem(
67-
files: Dictionary(uniqueKeysWithValues: bundles.map {
68-
(
69-
"\($0.path)/info.json",
70-
ByteString(
71-
json: generateInfoJSON(artifacts: $0.artifacts)
72-
)
73-
)
74-
})
97+
98+
let fileSystem = try InMemoryFileSystem(
99+
files: Dictionary(
100+
uniqueKeysWithValues: bundles.flatMap {
101+
try generateBundleFiles(bundle: $0)
102+
}
103+
)
75104
)
76105

77106
let swiftSDKsDirectory = try AbsolutePath(validating: "/sdks")
@@ -208,4 +237,34 @@ final class SwiftSDKBundleTests: XCTestCase {
208237

209238
XCTAssertEqual(validBundles.count, bundles.count)
210239
}
240+
241+
func testBundleSelection() async throws {
242+
let (fileSystem, bundles, swiftSDKsDirectory) = try generateTestFileSystem(
243+
bundleArtifacts: [
244+
.init(id: "\(testArtifactID)1", supportedTriples: [arm64Triple]),
245+
.init(id: "\(testArtifactID)2", supportedTriples: [i686Triple])
246+
]
247+
)
248+
let system = ObservabilitySystem.makeForTesting()
249+
250+
for bundle in bundles {
251+
try await SwiftSDKBundle.install(
252+
bundlePathOrURL: bundle.path,
253+
swiftSDKsDirectory: swiftSDKsDirectory,
254+
fileSystem,
255+
MockArchiver(),
256+
system.topScope
257+
)
258+
}
259+
260+
let sdk = try SwiftSDKBundle.selectBundle(
261+
fromBundlesAt: swiftSDKsDirectory,
262+
fileSystem: fileSystem,
263+
matching: "\(testArtifactID)1",
264+
hostTriple: Triple("arm64-apple-macosx14.0"),
265+
observabilityScope: system.topScope
266+
)
267+
268+
XCTAssertEqual(sdk.targetTriple, targetTriple)
269+
}
211270
}

0 commit comments

Comments
 (0)