Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Sources/PackageModel/ArtifactsArchiveMetadata.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ public struct ArtifactsArchiveMetadata: Equatable {

public struct Variant: Equatable {
public let path: RelativePath
public let supportedTriples: [Triple]
public let supportedTriples: [Triple]?

public init(path: RelativePath, supportedTriples: [Triple]) {
public init(path: RelativePath, supportedTriples: [Triple]?) {
self.path = path
self.supportedTriples = supportedTriples
}
Expand Down Expand Up @@ -121,7 +121,7 @@ extension ArtifactsArchiveMetadata.Variant: Decodable {

public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.supportedTriples = try container.decode([String].self, forKey: .supportedTriples).map { try Triple($0) }
self.supportedTriples = try container.decodeIfPresent([String].self, forKey: .supportedTriples)?.map { try Triple($0) }
self.path = try RelativePath(validating: container.decode(String.self, forKey: .path))
}
}
21 changes: 15 additions & 6 deletions Sources/PackageModel/SwiftSDKs/SwiftSDKBundle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,19 @@ public struct SwiftSDKBundle {
public var name: String { path.basename }
}

extension SwiftSDKBundle.Variant {
/// Whether the given host triple is supported by this SDK variant
internal func isSupporting(hostTriple: Triple) -> Bool {
guard let supportedTriples = metadata.supportedTriples else {
// No supportedTriples means the SDK can be universally usable
return true
}
return supportedTriples.contains(where: { variantTriple in
hostTriple.isRuntimeCompatible(with: variantTriple)
})
}
}

extension [SwiftSDKBundle] {
/// Select a Swift SDK with a given artifact ID from a `self` array of available Swift SDKs.
/// - Parameters:
Expand All @@ -48,7 +61,7 @@ extension [SwiftSDKBundle] {
}

for variant in variants {
guard variant.metadata.supportedTriples.contains(hostTriple) else {
guard variant.isSupporting(hostTriple: hostTriple) else {
continue
}

Expand Down Expand Up @@ -77,11 +90,7 @@ extension [SwiftSDKBundle] {
for bundle in self {
for (artifactID, variants) in bundle.artifacts {
for variant in variants {
guard variant.metadata.supportedTriples.contains(where: { variantTriple in
hostTriple.isRuntimeCompatible(with: variantTriple)
}) else {
continue
}
guard variant.isSupporting(hostTriple: hostTriple) else { continue }

for swiftSDK in variant.swiftSDKs {
if artifactID == selector {
Expand Down
5 changes: 4 additions & 1 deletion Sources/SPMBuildCore/BinaryTarget+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ extension BinaryTarget {
// Filter supported triples with versionLessTriple and pass into
// ExecutableInfo; empty if non matching triples found.
try entry.value.variants.map {
let filteredSupportedTriples = try $0.supportedTriples
guard let supportedTriples = $0.supportedTriples else {
throw StringError("No \"supportedTriples\" found in the artifact metadata for \(entry.key) in \(self.artifactPath)")
}
let filteredSupportedTriples = try supportedTriples
.filter { try $0.withoutVersion() == versionLessTriple }
return ExecutableInfo(
name: entry.key,
Expand Down
61 changes: 61 additions & 0 deletions Tests/PackageModelTests/SwiftSDKTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ private let bundleRootPath = try! AbsolutePath(validating: "/tmp/cross-toolchain
private let toolchainBinDir = RelativePath("swift.xctoolchain/usr/bin")
private let sdkRootDir = RelativePath("ubuntu-jammy.sdk")
private let hostTriple = try! Triple("arm64-apple-darwin22.1.0")
private let olderHostTriple = try! Triple("arm64-apple-darwin20.1.0")
private let linuxGNUTargetTriple = try! Triple("x86_64-unknown-linux-gnu")
private let linuxMuslTargetTriple = try! Triple("x86_64-unknown-linux-musl")
private let extraFlags = BuildFlags(
Expand Down Expand Up @@ -291,6 +292,12 @@ private let parsedDestinationV2Musl = SwiftSDK(
pathsConfiguration: .init(sdkRootPath: sdkRootAbsolutePath)
)

private let parsedDestinationForOlderHost = SwiftSDK(
targetTriple: linuxMuslTargetTriple,
toolset: .init(toolchainBinDir: toolchainBinAbsolutePath, buildFlags: extraFlags),
pathsConfiguration: .init(sdkRootPath: sdkRootAbsolutePath)
)

private let parsedToolsetNoRootDestination = SwiftSDK(
targetTriple: linuxGNUTargetTriple,
toolset: .init(
Expand Down Expand Up @@ -520,6 +527,24 @@ final class DestinationTests: XCTestCase {
swiftSDKs: [parsedDestinationV2Musl]
),
],
"id4": [
.init(
metadata: .init(
path: "id4",
supportedTriples: [olderHostTriple]
),
swiftSDKs: [parsedDestinationForOlderHost]
),
],
"id5": [
.init(
metadata: .init(
path: "id5",
supportedTriples: nil
),
swiftSDKs: [parsedDestinationV2GNU]
),
],
]
),
]
Expand Down Expand Up @@ -553,5 +578,41 @@ final class DestinationTests: XCTestCase {
),
parsedDestinationV2Musl
)

// Newer hostTriple should match with older supportedTriples
XCTAssertEqual(
bundles.selectSwiftSDK(
id: "id4",
hostTriple: hostTriple,
targetTriple: linuxMuslTargetTriple
),
parsedDestinationForOlderHost
)
XCTAssertEqual(
bundles.selectSwiftSDK(
matching: "id4",
hostTriple: hostTriple,
observabilityScope: system.topScope
),
parsedDestinationForOlderHost
)

// nil supportedTriples should match with any hostTriple
XCTAssertEqual(
bundles.selectSwiftSDK(
id: "id5",
hostTriple: hostTriple,
targetTriple: linuxGNUTargetTriple
),
parsedDestinationV2GNU
)
XCTAssertEqual(
bundles.selectSwiftSDK(
matching: "id5",
hostTriple: hostTriple,
observabilityScope: system.topScope
),
parsedDestinationV2GNU
)
}
}
57 changes: 57 additions & 0 deletions Tests/SPMBuildCoreTests/ArtifactsArchiveMetadataTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,61 @@ final class ArtifactsArchiveMetadataTests: XCTestCase {
]
))
}
func testParseMetadataWithoutSupportedTriple() throws {
let fileSystem = InMemoryFileSystem()
try fileSystem.writeFileContents(
"/info.json",
string: """
{
"schemaVersion": "1.0",
"artifacts": {
"protocol-buffer-compiler": {
"type": "executable",
"version": "3.5.1",
"variants": [
{
"path": "x86_64-apple-macosx/protoc"
},
{
"path": "x86_64-unknown-linux-gnu/protoc",
"supportedTriples": null
}
]
}
}
}
"""
)

let metadata = try ArtifactsArchiveMetadata.parse(fileSystem: fileSystem, rootPath: .root)
XCTAssertEqual(metadata, ArtifactsArchiveMetadata(
schemaVersion: "1.0",
artifacts: [
"protocol-buffer-compiler": ArtifactsArchiveMetadata.Artifact(
type: .executable,
version: "3.5.1",
variants: [
ArtifactsArchiveMetadata.Variant(
path: "x86_64-apple-macosx/protoc",
supportedTriples: nil
),
ArtifactsArchiveMetadata.Variant(
path: "x86_64-unknown-linux-gnu/protoc",
supportedTriples: nil
),
]
),
]
))

let binaryTarget = BinaryTarget(
name: "protoc", kind: .artifactsArchive, path: .root, origin: .local
)
// No supportedTriples with binaryTarget should be rejected
XCTAssertThrowsError(
try binaryTarget.parseArtifactArchives(
for: Triple("x86_64-apple-macosx"), fileSystem: fileSystem
)
)
}
}