Skip to content

Commit 99bab1c

Browse files
authored
Update Swift SDK nomenclature (#6678)
Introduced `SwiftSDKMetadataV4` type that uses `targetTriple` instead of `runTimeTriple`. We're keeping the previous v3 schema for better error handling in case v3 schema ended up being used in the wild during Swift 5.9 development cycle. The plan is to deprecate v3 and earlier schemas in a future change. `buildTimeTriple` and `runTimeTriple` renamed to `hostTriple` and `targetTriple` across the codebase, destinations renamed to Swift SDKs where possible without a broader disruption. Full renaming of the `Destination` type to `SwiftSDK` would come in a separate change to reduce the diff for this one.
1 parent d3df557 commit 99bab1c

15 files changed

+386
-140
lines changed

Sources/CoreCommands/SwiftTool.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ public final class SwiftTool {
736736
{
737737
destination = matchingDestination
738738
} else {
739-
return .failure(DestinationError.noDestinationsDecoded(customDestination))
739+
return .failure(SwiftSDKError.noSwiftSDKDecoded(customDestination))
740740
}
741741
} else if let triple = options.build.customCompileTriple,
742742
let targetDestination = Destination.defaultDestination(for: triple, host: hostDestination)

Sources/PackageModel/Destination.swift

Lines changed: 149 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ import enum TSCBasic.ProcessEnv
1818

1919
import struct TSCUtility.Version
2020

21-
/// Errors related to cross-compilation destinations.
22-
public enum DestinationError: Swift.Error {
21+
/// Errors related to Swift SDKs.
22+
public enum SwiftSDKError: Swift.Error {
2323
/// A passed argument is neither a valid file system path nor a URL.
2424
case invalidPathOrURL(String)
2525

@@ -32,67 +32,67 @@ public enum DestinationError: Swift.Error {
3232
/// Name of the destination bundle is not valid.
3333
case invalidBundleName(String)
3434

35-
/// No valid destinations were decoded from a destination file.
36-
case noDestinationsDecoded(AbsolutePath)
35+
/// No valid Swift SDKs were decoded from a metadata file.
36+
case noSwiftSDKDecoded(AbsolutePath)
3737

3838
/// Path used for storing destination configuration data is not a directory.
3939
case pathIsNotDirectory(AbsolutePath)
4040

41-
/// A destination couldn't be serialized with the latest serialization schema, potentially because it
41+
/// Swift SDK metadata couldn't be serialized with the latest serialization schema, potentially because it
4242
/// was deserialized from an earlier incompatible schema version or initialized manually with properties
4343
/// required for initialization missing.
44-
case unserializableDestination
44+
case unserializableMetadata
4545

46-
/// No configuration values are available for this destination and run-time triple.
47-
case destinationNotFound(artifactID: String, builtTimeTriple: Triple, runTimeTriple: Triple)
46+
/// No configuration values are available for this Swift SDK and target triple.
47+
case swiftSDKNotFound(artifactID: String, hostTriple: Triple, targetTriple: Triple)
4848

49-
/// A destination bundle with this name is already installed, can't install a new bundle with the same name.
50-
case destinationBundleAlreadyInstalled(bundleName: String)
49+
/// A Swift SDK bundle with this name is already installed, can't install a new bundle with the same name.
50+
case swiftSDKBundleAlreadyInstalled(bundleName: String)
5151

52-
/// A destination with this artifact ID is already installed. Can't install a new bundle with this artifact,
52+
/// A Swift SDK with this artifact ID is already installed. Can't install a new bundle with this artifact,
5353
/// installed artifact IDs are expected to be unique.
54-
case destinationArtifactAlreadyInstalled(installedBundleName: String, newBundleName: String, artifactID: String)
54+
case swiftSDKArtifactAlreadyInstalled(installedBundleName: String, newBundleName: String, artifactID: String)
5555

5656
#if os(macOS)
5757
/// Quarantine attribute should be removed by the `xattr` command from an installed bundle.
5858
case quarantineAttributePresent(bundlePath: AbsolutePath)
5959
#endif
6060
}
6161

62-
extension DestinationError: CustomStringConvertible {
62+
extension SwiftSDKError: CustomStringConvertible {
6363
public var description: String {
6464
switch self {
6565
case .invalidPathOrURL(let argument):
6666
return "`\(argument)` is neither a valid filesystem path nor a URL."
6767
case .invalidSchemaVersion:
68-
return "unsupported destination file schema version"
68+
return "unsupported Swift SDK file schema version"
6969
case .invalidInstallation(let problem):
7070
return problem
7171
case .invalidBundleName(let name):
7272
return """
7373
invalid bundle name `\(name)`, unpacked Swift SDK bundles are expected to have `.artifactbundle` extension
7474
"""
75-
case .noDestinationsDecoded(let path):
76-
return "no valid Swift SDKs were decoded from a destination file at path `\(path)`"
75+
case .noSwiftSDKDecoded(let path):
76+
return "no valid Swift SDKs were decoded from a metadata file at path `\(path)`"
7777
case .pathIsNotDirectory(let path):
7878
return "path expected to be a directory is not a directory or doesn't exist: `\(path)`"
79-
case .unserializableDestination:
79+
case .unserializableMetadata:
8080
return """
8181
Swift SDK configuration couldn't be serialized with the latest serialization schema, potentially because \
8282
it was deserialized from an earlier incompatible schema version or initialized manually with missing \
8383
properties required for initialization
8484
"""
85-
case .destinationNotFound(let artifactID, let buildTimeTriple, let runTimeTriple):
85+
case .swiftSDKNotFound(let artifactID, let hostTriple, let targetTriple):
8686
return """
87-
Swift SDK with ID `\(artifactID)`, build-time triple \(buildTimeTriple), and run-time triple \
88-
\(runTimeTriple) is not currently installed.
87+
Swift SDK with ID `\(artifactID)`, host triple \(hostTriple), and target triple \(targetTriple) is not \
88+
currently installed.
8989
"""
90-
case .destinationBundleAlreadyInstalled(let bundleName):
90+
case .swiftSDKBundleAlreadyInstalled(let bundleName):
9191
return """
9292
Swift SDK bundle with name `\(bundleName)` is already installed. Can't install a new bundle \
9393
with the same name.
9494
"""
95-
case .destinationArtifactAlreadyInstalled(let installedBundleName, let newBundleName, let artifactID):
95+
case .swiftSDKArtifactAlreadyInstalled(let installedBundleName, let newBundleName, let artifactID):
9696
return """
9797
A Swift SDK with artifact ID `\(artifactID)` is already included in an installed bundle with name \
9898
`\(installedBundleName)`. Can't install a new bundle `\(newBundleName)` with this artifact, artifact IDs \
@@ -242,7 +242,10 @@ public struct Destination: Equatable {
242242
/// - Parameters:
243243
/// - properties: properties of the destination for the given triple.
244244
/// - destinationDirectory: directory used for converting relative paths in `properties` to absolute paths.
245-
init(_ properties: SerializedDestinationV3.TripleProperties, destinationDirectory: AbsolutePath? = nil) throws {
245+
fileprivate init(
246+
_ properties: SerializedDestinationV3.TripleProperties,
247+
destinationDirectory: AbsolutePath? = nil
248+
) throws {
246249
if let destinationDirectory {
247250
self.init(
248251
sdkRootPath: try AbsolutePath(validating: properties.sdkRootPath, relativeTo: destinationDirectory),
@@ -284,6 +287,52 @@ public struct Destination: Equatable {
284287
}
285288
}
286289

290+
/// Initialize paths configuration from values deserialized using v4 schema.
291+
/// - Parameters:
292+
/// - properties: properties of a Swift SDK for the given triple.
293+
/// - swiftSDKDirectory: directory used for converting relative paths in `properties` to absolute paths.
294+
fileprivate init(_ properties: SwiftSDKMetadataV4.TripleProperties, swiftSDKDirectory: AbsolutePath? = nil) throws {
295+
if let swiftSDKDirectory {
296+
self.init(
297+
sdkRootPath: try AbsolutePath(validating: properties.sdkRootPath, relativeTo: swiftSDKDirectory),
298+
swiftResourcesPath: try properties.swiftResourcesPath.map {
299+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
300+
},
301+
swiftStaticResourcesPath: try properties.swiftStaticResourcesPath.map {
302+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
303+
},
304+
includeSearchPaths: try properties.includeSearchPaths?.map {
305+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
306+
},
307+
librarySearchPaths: try properties.librarySearchPaths?.map {
308+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
309+
},
310+
toolsetPaths: try properties.toolsetPaths?.map {
311+
try AbsolutePath(validating: $0, relativeTo: swiftSDKDirectory)
312+
}
313+
)
314+
} else {
315+
self.init(
316+
sdkRootPath: try AbsolutePath(validating: properties.sdkRootPath),
317+
swiftResourcesPath: try properties.swiftResourcesPath.map {
318+
try AbsolutePath(validating: $0)
319+
},
320+
swiftStaticResourcesPath: try properties.swiftStaticResourcesPath.map {
321+
try AbsolutePath(validating: $0)
322+
},
323+
includeSearchPaths: try properties.includeSearchPaths?.map {
324+
try AbsolutePath(validating: $0)
325+
},
326+
librarySearchPaths: try properties.librarySearchPaths?.map {
327+
try AbsolutePath(validating: $0)
328+
},
329+
toolsetPaths: try properties.toolsetPaths?.map {
330+
try AbsolutePath(validating: $0)
331+
}
332+
)
333+
}
334+
}
335+
287336
public mutating func merge(with newConfiguration: Self) {
288337
if let sdkRootPath = newConfiguration.sdkRootPath {
289338
self.sdkRootPath = sdkRootPath
@@ -410,7 +459,7 @@ public struct Destination: Equatable {
410459
environment: environment
411460
).spm_chomp()
412461
guard !sdkPathStr.isEmpty else {
413-
throw DestinationError.invalidInstallation("default SDK not found")
462+
throw SwiftSDKError.invalidInstallation("default SDK not found")
414463
}
415464
sdkPath = try AbsolutePath(validating: sdkPathStr)
416465
}
@@ -571,12 +620,56 @@ extension Destination {
571620
destinationDirectory: destinationDirectory
572621
)
573622
}
623+
624+
case Version(4, 0, 0):
625+
let swiftSDKs = try decoder.decode(path: path, fileSystem: fileSystem, as: SwiftSDKMetadataV4.self)
626+
let swiftSDKDirectory = path.parentDirectory
627+
628+
return try swiftSDKs.targetTriples.map { triple, properties in
629+
let triple = try Triple(triple)
630+
631+
let pathStrings = properties.toolsetPaths ?? []
632+
let toolset = try pathStrings.reduce(into: Toolset(knownTools: [:], rootPaths: [])) {
633+
try $0.merge(
634+
with: Toolset(
635+
from: .init(validating: $1, relativeTo: swiftSDKDirectory),
636+
at: fileSystem,
637+
observabilityScope
638+
)
639+
)
640+
}
641+
642+
return try Destination(
643+
targetTriple: triple,
644+
properties: properties,
645+
toolset: toolset,
646+
swiftSDKDirectory: swiftSDKDirectory
647+
)
648+
}
574649
default:
575-
throw DestinationError.invalidSchemaVersion
650+
throw SwiftSDKError.invalidSchemaVersion
576651
}
577652
}
578653

579-
654+
/// Initialize new Swift SDK from values deserialized using v4 schema.
655+
/// - Parameters:
656+
/// - targetTriple: triple of the machine running code built with this Swift SDK.
657+
/// - properties: properties of the Swift SDK for the given triple.
658+
/// - toolset: combined toolset used by this Swift SDK.
659+
/// - swiftSDKDirectory: directory used for converting relative paths in `properties` to absolute paths.
660+
init(
661+
targetTriple: Triple,
662+
properties: SwiftSDKMetadataV4.TripleProperties,
663+
toolset: Toolset = .init(),
664+
swiftSDKDirectory: AbsolutePath? = nil
665+
) throws {
666+
self.init(
667+
targetTriple: targetTriple,
668+
toolset: toolset,
669+
pathsConfiguration: try .init(properties, swiftSDKDirectory: swiftSDKDirectory)
670+
)
671+
}
672+
580673
/// Initialize new destination from values deserialized using v3 schema.
581674
/// - Parameters:
582675
/// - runTimeTriple: triple of the machine running code built with this destination.
@@ -643,7 +736,7 @@ extension Destination {
643736
)
644737
)
645738
default:
646-
throw DestinationError.invalidSchemaVersion
739+
throw SwiftSDKError.invalidSchemaVersion
647740
}
648741
}
649742

@@ -653,12 +746,12 @@ extension Destination {
653746
/// from different schema versions or constructed manually without providing valid values for such properties.
654747
var serialized: (Triple, SerializedDestinationV3.TripleProperties) {
655748
get throws {
656-
guard let runTimeTriple = self.targetTriple, let sdkRootDir = self.pathsConfiguration.sdkRootPath else {
657-
throw DestinationError.unserializableDestination
749+
guard let targetTriple = self.targetTriple, let sdkRootDir = self.pathsConfiguration.sdkRootPath else {
750+
throw SwiftSDKError.unserializableMetadata
658751
}
659752

660753
return (
661-
runTimeTriple,
754+
targetTriple,
662755
.init(
663756
sdkRootPath: sdkRootDir.pathString,
664757
swiftResourcesPath: self.pathsConfiguration.swiftResourcesPath?.pathString,
@@ -748,3 +841,29 @@ struct SerializedDestinationV3: Decodable {
748841
/// Mapping of triple strings to corresponding properties of such run-time triple.
749842
let runTimeTriples: [String: TripleProperties]
750843
}
844+
845+
/// Represents v4 schema of `swift-sdk.json` (previously `destination.json`) files used for cross-compilation.
846+
struct SwiftSDKMetadataV4: Decodable {
847+
struct TripleProperties: Codable {
848+
/// Path relative to `swift-sdk.json` containing SDK root.
849+
var sdkRootPath: String
850+
851+
/// Path relative to `swift-sdk.json` containing Swift resources for dynamic linking.
852+
var swiftResourcesPath: String?
853+
854+
/// Path relative to `swift-sdk.json` containing Swift resources for static linking.
855+
var swiftStaticResourcesPath: String?
856+
857+
/// Array of paths relative to `swift-sdk.json` containing headers.
858+
var includeSearchPaths: [String]?
859+
860+
/// Array of paths relative to `swift-sdk.json` containing libraries.
861+
var librarySearchPaths: [String]?
862+
863+
/// Array of paths relative to `swift-sdk.json` containing toolset files.
864+
var toolsetPaths: [String]?
865+
}
866+
867+
/// Mapping of triple strings to corresponding properties of such target triple.
868+
let targetTriples: [String: TripleProperties]
869+
}

Sources/PackageModel/SwiftSDKBundle.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public struct SwiftSDKBundle {
171171
{
172172
bundlePath = originalBundlePath
173173
} else {
174-
throw DestinationError.invalidPathOrURL(bundlePathOrURL)
174+
throw SwiftSDKError.invalidPathOrURL(bundlePathOrURL)
175175
}
176176

177177
try await installIfValid(
@@ -205,16 +205,16 @@ public struct SwiftSDKBundle {
205205
let regex = try RegEx(pattern: "(.+\\.artifactbundle).*")
206206

207207
guard let bundleName = bundlePath.components.last else {
208-
throw DestinationError.invalidPathOrURL(bundlePath.pathString)
208+
throw SwiftSDKError.invalidPathOrURL(bundlePath.pathString)
209209
}
210210

211211
guard let unpackedBundleName = regex.matchGroups(in: bundleName).first?.first else {
212-
throw DestinationError.invalidBundleName(bundleName)
212+
throw SwiftSDKError.invalidBundleName(bundleName)
213213
}
214214

215215
let installedBundlePath = destinationsDirectory.appending(component: unpackedBundleName)
216216
guard !fileSystem.exists(installedBundlePath) else {
217-
throw DestinationError.destinationBundleAlreadyInstalled(bundleName: unpackedBundleName)
217+
throw SwiftSDKError.swiftSDKBundleAlreadyInstalled(bundleName: unpackedBundleName)
218218
}
219219

220220
// If there's no archive extension on the bundle name, assuming it's not archived and returning the same path.
@@ -246,7 +246,7 @@ public struct SwiftSDKBundle {
246246
#if os(macOS)
247247
// Check the quarantine attribute on bundles downloaded manually in the browser.
248248
guard !fileSystem.hasAttribute(.quarantine, bundlePath) else {
249-
throw DestinationError.quarantineAttributePresent(bundlePath: bundlePath)
249+
throw SwiftSDKError.quarantineAttributePresent(bundlePath: bundlePath)
250250
}
251251
#endif
252252

@@ -262,7 +262,7 @@ public struct SwiftSDKBundle {
262262
fileSystem.isDirectory(unpackedBundlePath),
263263
let bundleName = unpackedBundlePath.components.last
264264
else {
265-
throw DestinationError.pathIsNotDirectory(bundlePath)
265+
throw SwiftSDKError.pathIsNotDirectory(bundlePath)
266266
}
267267

268268
let installedBundlePath = destinationsDirectory.appending(component: bundleName)
@@ -283,7 +283,7 @@ public struct SwiftSDKBundle {
283283
for installedBundle in installedBundles {
284284
for artifactID in installedBundle.artifacts.keys {
285285
guard !newArtifactIDs.contains(artifactID) else {
286-
throw DestinationError.destinationArtifactAlreadyInstalled(
286+
throw SwiftSDKError.swiftSDKArtifactAlreadyInstalled(
287287
installedBundleName: installedBundle.name,
288288
newBundleName: validatedBundle.name,
289289
artifactID: artifactID
@@ -296,12 +296,12 @@ public struct SwiftSDKBundle {
296296
}
297297

298298
/// Parses metadata of an `.artifactbundle` and validates it as a bundle containing
299-
/// cross-compilation destinations.
299+
/// cross-compilation Swift SDKs.
300300
/// - Parameters:
301301
/// - bundlePath: path to the bundle root directory.
302302
/// - fileSystem: filesystem containing the bundle.
303303
/// - observabilityScope: observability scope to log validation warnings.
304-
/// - Returns: Validated `DestinationsBundle` containing validated `Destination` values for
304+
/// - Returns: Validated `SwiftSDKBundle` containing validated `Destination` values for
305305
/// each artifact and its variants.
306306
private static func parseAndValidate(
307307
bundlePath: AbsolutePath,
@@ -313,7 +313,7 @@ public struct SwiftSDKBundle {
313313
rootPath: bundlePath
314314
)
315315

316-
return try parsedManifest.validateDestinationBundle(
316+
return try parsedManifest.validateSwiftSDKBundle(
317317
bundlePath: bundlePath,
318318
fileSystem: fileSystem,
319319
observabilityScope: observabilityScope
@@ -322,7 +322,7 @@ public struct SwiftSDKBundle {
322322
}
323323

324324
extension ArtifactsArchiveMetadata {
325-
fileprivate func validateDestinationBundle(
325+
fileprivate func validateSwiftSDKBundle(
326326
bundlePath: AbsolutePath,
327327
fileSystem: FileSystem,
328328
observabilityScope: ObservabilityScope

0 commit comments

Comments
 (0)