Skip to content

Commit 17b6273

Browse files
committed
Add request to get preferred run destination for a platform
This can be useful when implementing a system that needs to configure the active run destination of a build request but only knows the platform that the user is requesting a build for, but no architecture etc.
1 parent 7adc227 commit 17b6273

File tree

4 files changed

+125
-3
lines changed

4 files changed

+125
-3
lines changed

Sources/SWBBuildService/Messages.swift

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,31 @@ private struct ClearAllCaches: MessageHandler {
15281528
}
15291529
}
15301530

1531+
private struct GetPlatformPreferredRunDestinationMsg: MessageHandler {
1532+
struct PlatformNotFoundError: Error, CustomStringConvertible {
1533+
let platform: String
1534+
var description: String { "Unknown platform '\(platform)'" }
1535+
}
1536+
struct UnknownPreferredArchError: Error, CustomStringConvertible {
1537+
let platform: String
1538+
var description: String { "Platform '\(platform)' does not specify a preferred architecture" }
1539+
}
1540+
1541+
func handle(request: Request, message: GetPlatformPreferredRunDestinationRequest) async throws -> GetPlatformPreferredRunDestinationResponse {
1542+
let session = try request.session(for: message)
1543+
guard let platform = session.core.platformRegistry.lookup(name: message.platform) else {
1544+
throw PlatformNotFoundError(platform: message.platform)
1545+
}
1546+
// All relevant platforms define a preferredArch, so the undefined_arch fallback case should never happen
1547+
// in practice, and indicates a serious issue occurred during plugin loading.
1548+
guard let targetArchitecture = platform.preferredArch else {
1549+
throw UnknownPreferredArchError(platform: message.platform)
1550+
}
1551+
let runDestination = RunDestinationInfo(platform: platform.name, sdk: platform.name, sdkVariant: nil, targetArchitecture: targetArchitecture, supportedArchitectures: [targetArchitecture], disableOnlyActiveArch: false, hostTargetedPlatform: nil)
1552+
return GetPlatformPreferredRunDestinationResponse(info: runDestination)
1553+
}
1554+
}
1555+
15311556
// MARK: ServiceExtension Support
15321557

15331558
public struct ServiceSessionMessageHandlers: ServiceExtension {
@@ -1593,6 +1618,7 @@ package struct ServiceMessageHandlers: ServiceExtension {
15931618
service.registerMessageHandler(GetStatisticsDumpMsg.self)
15941619
service.registerMessageHandler(GetBuildSettingsDescriptionDumpMsg.self)
15951620
service.registerMessageHandler(ExecuteCommandLineToolMsg.self)
1621+
service.registerMessageHandler(GetPlatformPreferredRunDestinationMsg.self)
15961622

15971623
service.registerMessageHandler(CreateXCFrameworkHandler.self)
15981624

@@ -1613,7 +1639,7 @@ package struct ServiceMessageHandlers: ServiceExtension {
16131639
service.registerMessageHandler(ComputeDependencyClosureMsg.self)
16141640
service.registerMessageHandler(ComputeDependencyGraphMsg.self)
16151641
service.registerMessageHandler(DumpBuildDependencyInfoMsg.self)
1616-
1642+
16171643
service.registerMessageHandler(MacroEvaluationMsg.self)
16181644
service.registerMessageHandler(AllExportedMacrosAndValuesMsg.self)
16191645
service.registerMessageHandler(BuildSettingsEditorInfoMsg.self)

Sources/SWBProtocol/Message.swift

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public struct PingRequest: RequestMessage, Equatable {
6565

6666
public struct SetConfigItemRequest: RequestMessage, Equatable {
6767
public typealias ResponseMessage = VoidResponse
68-
68+
6969
public static let name = "SET_CONFIG_ITEM"
7070

7171
public let key: String
@@ -286,6 +286,33 @@ public struct GetBuildSettingsDescriptionRequest: SessionMessage, RequestMessage
286286
}
287287
}
288288

289+
/// Get the preferred run destination for a given platform
290+
public struct GetPlatformPreferredRunDestinationRequest: SessionMessage, RequestMessage, Equatable, SerializableCodable {
291+
public typealias ResponseMessage = GetPlatformPreferredRunDestinationResponse
292+
293+
public static let name = "GET_PLATFORM_PREFERRED_RUN_DESTINATION_REQUEST"
294+
295+
public let sessionHandle: String
296+
297+
/// The name of the platform to get the run destination for, eg. `macosx`, `iphoneos`, `iphonesimulator`
298+
public let platform: String
299+
300+
public init(sessionHandle: String, platform: String) {
301+
self.sessionHandle = sessionHandle
302+
self.platform = platform
303+
}
304+
}
305+
306+
public struct GetPlatformPreferredRunDestinationResponse: Message, Equatable, SerializableCodable {
307+
public static let name = "GET_PLATFORM_PREFERRED_RUN_DESTINATION_RESPONSE"
308+
309+
public let info: RunDestinationInfo
310+
311+
public init(info: RunDestinationInfo) {
312+
self.info = info
313+
}
314+
}
315+
289316
public struct CreateXCFrameworkRequest: RequestMessage, Equatable, SerializableCodable {
290317
public typealias ResponseMessage = StringResponse
291318

@@ -1171,6 +1198,9 @@ public struct IPCMessage: Serializable, Sendable {
11711198
GetBuildSettingsDescriptionRequest.self,
11721199
ExecuteCommandLineToolRequest.self,
11731200

1201+
GetPlatformPreferredRunDestinationRequest.self,
1202+
GetPlatformPreferredRunDestinationResponse.self,
1203+
11741204
CreateSessionRequest.self,
11751205
CreateSessionResponse.self,
11761206
SetSessionSystemInfoRequest.self,

Sources/SwiftBuild/SWBBuildServiceSession.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import Foundation
1414

15-
import SWBProtocol
15+
public import SWBProtocol
1616
import SWBUtil
1717

1818
public enum SwiftBuildServicePIFObjectType: Sendable {
@@ -582,6 +582,19 @@ public final class SWBBuildServiceSession: Sendable {
582582
try await service.send(request: DeveloperPathRequest(sessionHandle: uid)).value
583583
}
584584

585+
public func preferredRunDestination(forPlatform platformName: String) async throws -> SWBRunDestinationInfo {
586+
let runDestination = try await service.send(request: GetPlatformPreferredRunDestinationRequest(sessionHandle: uid, platform: platformName)).info
587+
return SWBRunDestinationInfo(
588+
platform: runDestination.platform,
589+
sdk: runDestination.sdk,
590+
sdkVariant: runDestination.sdkVariant,
591+
targetArchitecture: runDestination.targetArchitecture,
592+
supportedArchitectures: runDestination.supportedArchitectures.elements,
593+
disableOnlyActiveArch: runDestination.disableOnlyActiveArch,
594+
hostTargetedPlatform: runDestination.hostTargetedPlatform
595+
)
596+
}
597+
585598
/// Set the session system information.
586599
public func setSystemInfo(_ systemInfo: SWBSystemInfo) async throws {
587600
_ = try await service.send(request: SetSessionSystemInfoRequest(sessionHandle: uid, operatingSystemVersion: Version(systemInfo.operatingSystemVersion), productBuildVersion: systemInfo.productBuildVersion, nativeArchitecture: systemInfo.nativeArchitecture))
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import Testing
14+
import SwiftBuild
15+
import SwiftBuildTestSupport
16+
import SWBTestSupport
17+
@_spi(Testing) import SWBUtil
18+
19+
@Suite
20+
fileprivate struct PreferredRunDestinationTests {
21+
@Test(.requireSDKs(.macOS))
22+
func platformExists() async throws {
23+
try await withTemporaryDirectory { (temporaryDirectory: NamedTemporaryDirectory) in
24+
try await withAsyncDeferrable { deferrable in
25+
let testSession = try await TestSWBSession(temporaryDirectory: temporaryDirectory)
26+
await deferrable.addBlock {
27+
await #expect(throws: Never.self) {
28+
try await testSession.close()
29+
}
30+
}
31+
let runDestination = try await testSession.session.preferredRunDestination(forPlatform: "macosx")
32+
#expect(runDestination.sdk == "macosx")
33+
}
34+
}
35+
}
36+
37+
@Test
38+
func unknownPlatform() async throws {
39+
try await withTemporaryDirectory { (temporaryDirectory: NamedTemporaryDirectory) in
40+
try await withAsyncDeferrable { deferrable in
41+
let testSession = try await TestSWBSession(temporaryDirectory: temporaryDirectory)
42+
await deferrable.addBlock {
43+
await #expect(throws: Never.self) {
44+
try await testSession.close()
45+
}
46+
}
47+
await #expect(throws: (any Error).self) {
48+
try await testSession.session.preferredRunDestination(forPlatform: "unknown_platform")
49+
}
50+
}
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)