Skip to content

Commit 5123bf0

Browse files
authored
Use new Swift Build run destination API for SDK's (#9527)
When using an SDK with the `--swift-sdk` build parameter this information is provided to Swift Build as part of the build request so that it can use it instead of the host SDK.
1 parent 4e54850 commit 5123bf0

8 files changed

Lines changed: 114 additions & 45 deletions

File tree

.swift-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6.2.0
1+
6.2.3

Sources/PackageModel/SwiftSDKs/SwiftSDK.swift

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,8 @@ public struct SwiftSDK: Equatable {
265265
/// deserialization.
266266
public private(set) var toolset: Toolset
267267

268+
public private(set) var swiftSDKManifest: Basics.AbsolutePath?
269+
268270
/// The paths associated with a Swift SDK. The Path type can be a `String`
269271
/// to encapsulate the arguments for the `SwiftSDKConfigurationStore.configure`
270272
/// function, or can be a fully-realized `AbsolutePath` when deserialized from a configuration.
@@ -499,12 +501,14 @@ public struct SwiftSDK: Equatable {
499501
hostTriple: Triple? = nil,
500502
targetTriple: Triple? = nil,
501503
toolset: Toolset,
504+
swiftSDKManifest: Basics.AbsolutePath? = nil,
502505
pathsConfiguration: PathsConfiguration<Basics.AbsolutePath>,
503506
xctestSupport: XCTestSupport = .supported
504507
) {
505508
self.hostTriple = hostTriple
506509
self.targetTriple = targetTriple
507510
self.toolset = toolset
511+
self.swiftSDKManifest = swiftSDKManifest
508512
self.pathsConfiguration = pathsConfiguration
509513
self.xctestSupport = xctestSupport
510514
}
@@ -942,7 +946,8 @@ extension SwiftSDK {
942946
targetTriple: triple,
943947
properties: properties,
944948
toolset: toolset,
945-
swiftSDKDirectory: swiftSDKDirectory
949+
swiftSDKDirectory: swiftSDKDirectory,
950+
swiftSDKManifest: path,
946951
)
947952
}
948953

@@ -973,7 +978,8 @@ extension SwiftSDK {
973978
targetTriple: triple,
974979
properties: properties,
975980
toolset: toolset,
976-
swiftSDKDirectory: swiftSDKDirectory
981+
swiftSDKDirectory: swiftSDKDirectory,
982+
swiftSDKManifest: path,
977983
)
978984
}
979985
default:
@@ -991,11 +997,13 @@ extension SwiftSDK {
991997
targetTriple: Triple,
992998
properties: SwiftSDKMetadataV4.TripleProperties,
993999
toolset: Toolset = .init(),
994-
swiftSDKDirectory: Basics.AbsolutePath? = nil
1000+
swiftSDKDirectory: Basics.AbsolutePath? = nil,
1001+
swiftSDKManifest: Basics.AbsolutePath? = nil,
9951002
) throws {
9961003
self.init(
9971004
targetTriple: targetTriple,
9981005
toolset: toolset,
1006+
swiftSDKManifest: swiftSDKManifest,
9991007
pathsConfiguration: try .init(properties, swiftSDKDirectory: swiftSDKDirectory)
10001008
)
10011009
}
@@ -1010,11 +1018,13 @@ extension SwiftSDK {
10101018
targetTriple: Triple,
10111019
properties: SerializedDestinationV3.TripleProperties,
10121020
toolset: Toolset = .init(),
1013-
swiftSDKDirectory: Basics.AbsolutePath? = nil
1021+
swiftSDKDirectory: Basics.AbsolutePath? = nil,
1022+
swiftSDKManifest: Basics.AbsolutePath? = nil,
10141023
) throws {
10151024
self.init(
10161025
targetTriple: targetTriple,
10171026
toolset: toolset,
1027+
swiftSDKManifest: swiftSDKManifest,
10181028
pathsConfiguration: try .init(properties, swiftSDKDirectory: swiftSDKDirectory)
10191029
)
10201030
}

Sources/PackageModel/Toolchain.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ public protocol Toolchain {
7575
/// Additional flags to be passed to the C++ compiler.
7676
@available(*, deprecated, message: "use extraFlags.cxxCompilerFlags instead")
7777
var extraCPPFlags: [String] { get }
78+
79+
var swiftSDK: SwiftSDK { get }
7880
}
7981

8082
extension Toolchain {

Sources/SwiftBuildSupport/SwiftBuildSystem.swift

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -703,36 +703,45 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
703703
}
704704

705705
private func makeRunDestination() -> SwiftBuild.SWBRunDestinationInfo {
706-
let platformName: String
707-
let sdkName: String
708-
if self.buildParameters.triple.isAndroid() {
709-
// Android triples are identified by the environment part of the triple
710-
platformName = "android"
711-
sdkName = platformName
712-
} else if self.buildParameters.triple.isWasm {
713-
// Swift Build uses webassembly instead of wasi as the platform name
714-
platformName = "webassembly"
715-
sdkName = platformName
706+
if let sdkManifestPath = self.buildParameters.toolchain.swiftSDK.swiftSDKManifest {
707+
return SwiftBuild.SWBRunDestinationInfo(
708+
buildTarget: .swiftSDK(sdkManifestPath: sdkManifestPath.pathString, triple: self.buildParameters.triple.tripleString),
709+
targetArchitecture: buildParameters.triple.archName,
710+
supportedArchitectures: [],
711+
disableOnlyActiveArch: (buildParameters.architectures?.count ?? 1) > 1,
712+
)
716713
} else {
717-
platformName = self.buildParameters.triple.darwinPlatform?.platformName ?? self.buildParameters.triple.osNameUnversioned
718-
sdkName = platformName
719-
}
714+
let platformName: String
715+
let sdkName: String
720716

721-
let sdkVariant: String?
722-
if self.buildParameters.triple.environment == .macabi {
723-
sdkVariant = "iosmac"
724-
} else {
725-
sdkVariant = nil
726-
}
717+
if self.buildParameters.triple.isAndroid() {
718+
// Android triples are identified by the environment part of the triple
719+
platformName = "android"
720+
sdkName = platformName
721+
} else {
722+
platformName = self.buildParameters.triple.darwinPlatform?.platformName ?? self.buildParameters.triple.osNameUnversioned
723+
sdkName = platformName
724+
}
727725

728-
return SwiftBuild.SWBRunDestinationInfo(
729-
platform: platformName,
730-
sdk: sdkName,
731-
sdkVariant: sdkVariant,
732-
targetArchitecture: buildParameters.triple.archName,
733-
supportedArchitectures: [],
734-
disableOnlyActiveArch: (buildParameters.architectures?.count ?? 1) > 1
735-
)
726+
let sdkVariant: String?
727+
if self.buildParameters.triple.environment == .macabi {
728+
sdkVariant = "iosmac"
729+
} else {
730+
sdkVariant = nil
731+
}
732+
733+
return SwiftBuild.SWBRunDestinationInfo(
734+
buildTarget: .toolchainSDK(
735+
platform: platformName,
736+
sdk: sdkName,
737+
sdkVariant: sdkVariant
738+
),
739+
targetArchitecture: buildParameters.triple.archName,
740+
supportedArchitectures: [],
741+
disableOnlyActiveArch: (buildParameters.architectures?.count ?? 1) > 1,
742+
hostTargetedPlatform: nil
743+
)
744+
}
736745
}
737746

738747
internal func makeBuildParameters(
@@ -867,12 +876,19 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
867876
+ buildParameters.flags.swiftCompilerFlags.map { $0.shellEscaped() }
868877
).joined(separator: " ")
869878

870-
settings["OTHER_LDFLAGS"] = (
871-
verboseFlag + // clang will be invoked to link so the verbose flag is valid for it
872-
["$(inherited)"]
873-
+ buildParameters.toolchain.extraFlags.linkerFlags.asSwiftcLinkerFlags().map { $0.shellEscaped() }
874-
+ buildParameters.flags.linkerFlags.asSwiftcLinkerFlags().map { $0.shellEscaped() }
875-
).joined(separator: " ")
879+
let inherited = ["$(inherited)"]
880+
881+
let buildParametersLinkFlags =
882+
buildParameters.toolchain.extraFlags.linkerFlags.asSwiftcLinkerFlags().map { $0.shellEscaped() }
883+
+ buildParameters.flags.linkerFlags.asSwiftcLinkerFlags().map { $0.shellEscaped() }
884+
885+
var otherLdFlags =
886+
verboseFlag // clang will be invoked to link so the verbose flag is valid for it
887+
+ inherited
888+
889+
otherLdFlags += buildParametersLinkFlags
890+
891+
settings["OTHER_LDFLAGS"] = otherLdFlags.joined(separator: " ")
876892

877893
// Optionally also set the list of architectures to build for.
878894
if let architectures = buildParameters.architectures, !architectures.isEmpty {

Sources/_InternalBuildTestSupport/MockBuildTestHelper.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import Testing
2828
public func mockBuildPlan(
2929
buildPath: AbsolutePath? = nil,
3030
environment: BuildEnvironment,
31-
toolchain: PackageModel.Toolchain = MockToolchain(),
31+
toolchain: PackageModel.Toolchain = try! MockToolchain(),
3232
graph: ModulesGraph,
3333
commonFlags: PackageModel.BuildFlags = .init(),
3434
indexStoreMode: BuildParameters.IndexStoreMode = .off,
@@ -61,7 +61,7 @@ public func mockBuildPlan(
6161
config: BuildConfiguration = .debug,
6262
triple: Basics.Triple? = nil,
6363
platform: PackageModel.Platform? = nil,
64-
toolchain: PackageModel.Toolchain = MockToolchain(),
64+
toolchain: PackageModel.Toolchain = try! MockToolchain(),
6565
graph: ModulesGraph,
6666
commonFlags: PackageModel.BuildFlags = .init(),
6767
indexStoreMode: BuildParameters.IndexStoreMode = .off,

Sources/_InternalTestSupport/MockBuildTestHelper.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public struct MockToolchain: PackageModel.Toolchain {
4141
public let swiftPMLibrariesLocation = ToolchainConfiguration.SwiftPMLibrariesLocation(
4242
manifestLibraryPath: AbsolutePath("/fake/manifestLib/path"), pluginLibraryPath: AbsolutePath("/fake/pluginLibrary/path")
4343
)
44+
public var swiftSDK: PackageModel.SwiftSDK
4445

4546
public func getClangCompiler() throws -> AbsolutePath {
4647
"/fake/path/to/clang"
@@ -54,10 +55,11 @@ public struct MockToolchain: PackageModel.Toolchain {
5455
#endif
5556
}
5657

57-
public init(swiftResourcesPath: AbsolutePath? = nil) {
58+
public init(swiftResourcesPath: AbsolutePath? = nil) throws {
5859
self.swiftResourcesPath = swiftResourcesPath
5960
self.metalToolchainPath = nil
6061
self.metalToolchainId = nil
62+
self.swiftSDK = try .hostSwiftSDK()
6163
}
6264
}
6365

@@ -84,7 +86,7 @@ public func mockBuildParameters(
8486
destination: BuildParameters.Destination,
8587
buildPath: AbsolutePath? = nil,
8688
config: BuildConfiguration = .debug,
87-
toolchain: PackageModel.Toolchain = MockToolchain(),
89+
toolchain: PackageModel.Toolchain = try! MockToolchain(),
8890
flags: PackageModel.BuildFlags = PackageModel.BuildFlags(),
8991
buildSystemKind: BuildSystemProvider.Kind = .native,
9092
shouldLinkStaticSwiftStdlib: Bool = false,

Tests/BuildTests/ClangTargetBuildDescriptionTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ final class ClangTargetBuildDescriptionTests: XCTestCase {
2626
}
2727

2828
func testSwiftCorelibsFoundationIncludeWorkaround() throws {
29-
let toolchain = MockToolchain(swiftResourcesPath: AbsolutePath("/fake/path/lib/swift"))
29+
let toolchain = try MockToolchain(swiftResourcesPath: AbsolutePath("/fake/path/lib/swift"))
3030

3131
let macosParameters = mockBuildParameters(destination: .target, toolchain: toolchain, triple: .macOS)
3232
let linuxParameters = mockBuildParameters(destination: .target, toolchain: toolchain, triple: .arm64Linux)

Tests/PackageModelTests/SwiftSDKTests.swift

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ private let parsedToolsetNoRootDestination = SwiftSDK(
341341
],
342342
rootPaths: []
343343
),
344+
swiftSDKManifest: toolsetNoRootSwiftSDKv4.path,
344345
pathsConfiguration: .init(
345346
sdkRootPath: bundleRootPath.appending(sdkRootDir),
346347
toolsetPaths: ["/tools/otherToolsNoRoot.json"]
@@ -359,6 +360,7 @@ private let parsedToolsetRootDestination = SwiftSDK(
359360
],
360361
rootPaths: [try! AbsolutePath(validating: "/custom")]
361362
),
363+
swiftSDKManifest: toolsetRootSwiftSDKv4.path,
362364
pathsConfiguration: .init(
363365
sdkRootPath: bundleRootPath.appending(sdkRootDir),
364366
toolsetPaths: ["/tools/someToolsWithRoot.json", "/tools/otherToolsNoRoot.json"]
@@ -376,6 +378,7 @@ private let parsedToolsetNoSDKRootPathDestination = SwiftSDK(
376378
],
377379
rootPaths: []
378380
),
381+
swiftSDKManifest: androidWithoutSDKRootPathSwiftSDKv4.path,
379382
pathsConfiguration: .init(
380383
sdkRootPath: nil,
381384
toolsetPaths: ["/tools/otherToolsNoRoot.json"]
@@ -455,7 +458,24 @@ final class SwiftSDKTests: XCTestCase {
455458
observabilityScope: observability
456459
)
457460

458-
XCTAssertEqual(toolsetNoRootDestinationV3Decoded, [parsedToolsetNoRootDestination])
461+
let parsedToolsetNoRootDestinationV3 = SwiftSDK(
462+
targetTriple: linuxGNUTargetTriple,
463+
toolset: .init(
464+
knownTools: [
465+
.librarian: .init(path: try! AbsolutePath(validating: "\(usrBinTools[.librarian]!)")),
466+
.linker: .init(path: try! AbsolutePath(validating: "\(usrBinTools[.linker]!)")),
467+
.debugger: .init(path: try! AbsolutePath(validating: "\(usrBinTools[.debugger]!)")),
468+
],
469+
rootPaths: []
470+
),
471+
swiftSDKManifest: toolsetNoRootDestinationV3.path,
472+
pathsConfiguration: .init(
473+
sdkRootPath: bundleRootPath.appending(sdkRootDir),
474+
toolsetPaths: ["/tools/otherToolsNoRoot.json"]
475+
.map { try! AbsolutePath(validating: $0) }
476+
)
477+
)
478+
XCTAssertEqual(toolsetNoRootDestinationV3Decoded, [parsedToolsetNoRootDestinationV3])
459479

460480
let toolsetRootDestinationV3Decoded = try SwiftSDK.decode(
461481
fromFile: toolsetRootDestinationV3.path,
@@ -464,7 +484,26 @@ final class SwiftSDKTests: XCTestCase {
464484
observabilityScope: observability
465485
)
466486

467-
XCTAssertEqual(toolsetRootDestinationV3Decoded, [parsedToolsetRootDestination])
487+
let parsedToolsetRootDestinationV3Decoded = SwiftSDK(
488+
targetTriple: linuxGNUTargetTriple,
489+
toolset: .init(
490+
knownTools: [
491+
.cCompiler: .init(extraCLIOptions: cCompilerOptions),
492+
.librarian: .init(path: try! AbsolutePath(validating: "\(usrBinTools[.librarian]!)")),
493+
.linker: .init(path: try! AbsolutePath(validating: "\(usrBinTools[.linker]!)")),
494+
.debugger: .init(path: try! AbsolutePath(validating: "\(usrBinTools[.debugger]!)")),
495+
],
496+
rootPaths: [try! AbsolutePath(validating: "/custom")]
497+
),
498+
swiftSDKManifest: toolsetRootDestinationV3.path,
499+
pathsConfiguration: .init(
500+
sdkRootPath: bundleRootPath.appending(sdkRootDir),
501+
toolsetPaths: ["/tools/someToolsWithRoot.json", "/tools/otherToolsNoRoot.json"]
502+
.map { try! AbsolutePath(validating: $0) }
503+
)
504+
)
505+
506+
XCTAssertEqual(toolsetRootDestinationV3Decoded, [parsedToolsetRootDestinationV3Decoded])
468507

469508
XCTAssertThrowsError(try SwiftSDK.decode(
470509
fromFile: missingToolsetDestinationV3.path,

0 commit comments

Comments
 (0)