Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
0756787
Swift SDK for WASM using the run destination
cmcgee1024 Dec 4, 2025
222f639
Restore the emit executable argument in Ld.xcspec
cmcgee1024 Dec 9, 2025
0211f9a
Override the rpath argument to the linker in the webassembly ld xcspe…
cmcgee1024 Dec 9, 2025
7a136b5
Move the platform registerSDK call to its original position
cmcgee1024 Dec 9, 2025
ae50208
Undo use of sdk.canonicalName instead of the provided canonical name
cmcgee1024 Dec 9, 2025
07993ad
Fix compile error in tests
cmcgee1024 Dec 9, 2025
d6bce25
Formatting
cmcgee1024 Dec 9, 2025
87af09f
Base the OTHER_LDFLAGS on the extra swift compiler settings
cmcgee1024 Dec 10, 2025
66cfd6c
Fix typo
cmcgee1024 Dec 10, 2025
6bdaeef
Introduce a new synthesizedSDK method for SDK registries that special…
cmcgee1024 Dec 10, 2025
6b5f572
Formatting and remove active run destination qualifier
cmcgee1024 Dec 10, 2025
4237bf4
Make explicit build target in run destination with both Apple and Swi…
cmcgee1024 Dec 12, 2025
ba56abd
Move the workaround for the UnixLd removal of the -sdk link argument …
cmcgee1024 Dec 12, 2025
2d02364
Rework the SWBBuildTarget API into a struct instead of an enum
cmcgee1024 Dec 16, 2025
afa0d52
Add a new platformName capability to PlatformInfoExtension, using tha…
cmcgee1024 Dec 16, 2025
95e4f38
Refactor name of appleSDK to toolchainSDK
cmcgee1024 Dec 17, 2025
e7cc4ae
Introduce compatibility with encoding/decoding of the build targets
cmcgee1024 Dec 17, 2025
f26b36b
Code review feedback
cmcgee1024 Dec 18, 2025
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
16 changes: 11 additions & 5 deletions Sources/SWBCore/BuildRequestContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,11 @@ extension BuildRequestContext {
func platformAndSDKVariant(for target: ConfiguredTarget) -> PlatformAndSDKVariant {
if hasEnabledIndexBuildArena,
let activeRunDestination = target.parameters.activeRunDestination,
let platform = workspaceContext.core.platformRegistry.lookup(name: activeRunDestination.platform) {
case let .toolchainSDK(platform: platform, _, sdkVariant: sdkVariant) = activeRunDestination.buildTarget,
let platform = workspaceContext.core.platformRegistry.lookup(name: platform) {
// Configured targets include their platform in parameters, we can use it directly and avoid the expense of `getCachedSettings()` calls.
// If in future `ConfiguredTarget` carries along an instance of its Settings, we can avoid this check and go back to using `Settings` without the cost of `getCachedSettings`.
return PlatformAndSDKVariant(platform: platform, sdkVariant: activeRunDestination.sdkVariant)
return PlatformAndSDKVariant(platform: platform, sdkVariant: sdkVariant)
} else {
let settings = getCachedSettings(target.parameters, target: target.target)
return PlatformAndSDKVariant(platform: settings.platform, sdkVariant: settings.sdkVariant?.name)
Expand Down Expand Up @@ -249,9 +250,14 @@ extension BuildRequestContext {
guard let destination = runDestination else {
return selectWithoutRunDestination()
}
if matchesPlatform(lhsPlatform, platformName: destination.platform, sdkVariant: destination.sdkVariant) { return lhs }
if matchesPlatform(rhsPlatform, platformName: destination.platform, sdkVariant: destination.sdkVariant) { return rhs }
guard let destinationPlatform = workspaceContext.core.platformRegistry.lookup(name: destination.platform) else {

guard case let .toolchainSDK(platform: platform, _, sdkVariant: sdkVariant) = destination.buildTarget else {
return selectWithoutRunDestination()
}

if matchesPlatform(lhsPlatform, platformName: platform, sdkVariant: sdkVariant) { return lhs }
if matchesPlatform(rhsPlatform, platformName: platform, sdkVariant: sdkVariant) { return rhs }
guard let destinationPlatform = workspaceContext.core.platformRegistry.lookup(name: platform) else {
return selectWithoutRunDestination()
}
if lhsPlatform.platform?.familyName != rhsPlatform.platform?.familyName {
Expand Down
19 changes: 15 additions & 4 deletions Sources/SWBCore/ConfiguredTarget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,11 @@ public final class ConfiguredTarget: Hashable, CustomStringConvertible, Serializ
if !parameters.isEmpty {
components.append(("parameters", parameters.joined(separator: "-")))
}
if specializeGuidForActiveRunDestination, let runDestination = self.parameters.activeRunDestination {
var runDestString = runDestination.platform
if let sdkVariant = runDestination.sdkVariant {
if specializeGuidForActiveRunDestination,
let runDestination = self.parameters.activeRunDestination,
case let .toolchainSDK(platform: platform, _, sdkVariant: sdkVariant) = runDestination.buildTarget {
var runDestString = platform
if let sdkVariant = sdkVariant {
runDestString += "+\(sdkVariant)"
}
components.append(("runDestination", runDestString))
Expand Down Expand Up @@ -106,8 +108,17 @@ public final class ConfiguredTarget: Hashable, CustomStringConvertible, Serializ
return nil
}
}

if specializeGuidForActiveRunDestination {
let discriminator = self.parameters.activeRunDestination.map{ "\($0.platform)-\($0.sdkVariant ?? "")" } ?? ""
let discriminator: String
switch self.parameters.activeRunDestination?.buildTarget {
case let .toolchainSDK(platform: platform, _, sdkVariant: sdkVariant):
discriminator = "\(platform)-\(sdkVariant ?? "")"
case let .swiftSDK(sdkManifestPath: sdkManifestPath, triple: triple):
discriminator = "\(sdkManifestPath)-\(triple)"
default:
discriminator = ""
}
parameters.append(discriminator)
}
return .init(id: ["target", target.name, target.guid, parameters.joined(separator: ":")].joined(separator: "-"))
Expand Down
31 changes: 20 additions & 11 deletions Sources/SWBCore/DependencyResolution.swift
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ struct SpecializationParameters: Hashable, CustomStringConvertible {
overrides["SUPPORTS_MACCATALYST"] = sdkVariant.name == MacCatalystInfo.sdkVariantName ? "YES" : "NO"
}
if let supportedPlatforms {
if let platform = parameters.activeRunDestination?.platform {
if case let .toolchainSDK(platform: platform, _, _) = parameters.activeRunDestination?.buildTarget {
// If the specialization matches the platform of the active run destination, we do not need to impose it.
if !supportedPlatforms.contains(platform) {
overrides["SUPPORTED_PLATFORMS"] = supportedPlatforms.joined(separator: " ")
Expand Down Expand Up @@ -258,9 +258,12 @@ struct SpecializationParameters: Hashable, CustomStringConvertible {
// This seems like an unfortunate way to get from the SDK to its platform. But SettingsBuilder.computeBoundProperties() creates a scope to evaluate the PLATFORM_NAME defined in the SDK's default properties, so maybe there isn't a clearly better way.
if let overridingSdk, let overridingPlatform = workspaceContext.core.platformRegistry.platforms.filter({ $0.sdks.contains(where: { $0.canonicalName == overridingSdk.canonicalName }) }).first {
platformName = overridingPlatform.name
} else if case let .toolchainSDK(platform: platform, _, _) = parameters.activeRunDestination?.buildTarget {
platformName = platform
} else {
platformName = parameters.activeRunDestination?.platform
platformName = nil
}

if platformName == nil {
if let overridingSdk = overridingSdk {
let platformNames = workspaceContext.core.platformRegistry.platforms.map { $0.name }
Expand All @@ -272,7 +275,7 @@ struct SpecializationParameters: Hashable, CustomStringConvertible {
// Otherwise there was no overriding SDK provided, and there is no active run destination (or somehow there's a destination without a platform). This is valid, but it's not clear to me what this means for specialization parameters.
}
let sdkSuffix: String?
if let sdk = parameters.activeRunDestination?.sdk {
if case let .toolchainSDK(_, sdk: sdk, _) = parameters.activeRunDestination?.buildTarget {
if let suffix = try? workspaceContext.sdkRegistry.lookup(sdk, activeRunDestination: parameters.activeRunDestination)?.canonicalNameSuffix, !suffix.isEmpty {
sdkSuffix = suffix
} else {
Expand All @@ -282,7 +285,13 @@ struct SpecializationParameters: Hashable, CustomStringConvertible {
} else {
sdkSuffix = nil
}
self.init(workspaceContext: workspaceContext, platformName: platformName, sdkVariantName: parameters.activeRunDestination?.sdkVariant, canonicalNameSuffix: sdkSuffix, diagnostics: diagnostics)
let sdkVariantName: String?
if case let .toolchainSDK(_, _, sdkVariant: sdkVariant) = parameters.activeRunDestination?.buildTarget {
sdkVariantName = sdkVariant
} else {
sdkVariantName = nil
}
self.init(workspaceContext: workspaceContext, platformName: platformName, sdkVariantName: sdkVariantName, canonicalNameSuffix: sdkSuffix, diagnostics: diagnostics)
}

fileprivate init(workspaceContext: WorkspaceContext, platformName: String?, sdkVariantName: String?, canonicalNameSuffix: String?, diagnostics: [Diagnostic] = []) {
Expand Down Expand Up @@ -532,12 +541,12 @@ extension SpecializationParameters {
let archName: String = platform.determineDefaultArchForIndexArena(preferredArch: workspaceContext.systemInfo?.nativeArchitecture, using: workspaceContext.core) ?? "unknown_arch"

for sdkVariant in matchingSDK.variants.keys.sorted() {
let runDestination = RunDestinationInfo(platform: platform.name, sdk: matchingSDK.canonicalName, sdkVariant: sdkVariant, targetArchitecture: archName, supportedArchitectures: [archName], disableOnlyActiveArch: false, hostTargetedPlatform: nil)
let runDestination = RunDestinationInfo(buildTarget: .toolchainSDK(platform: platform.name, sdk: matchingSDK.canonicalName, sdkVariant: sdkVariant), targetArchitecture: archName, supportedArchitectures: [archName], disableOnlyActiveArch: false, hostTargetedPlatform: nil)
let buildParams = buildRequest.parameters.replacing(activeRunDestination: runDestination, activeArchitecture: archName)
let specializationParams = SpecializationParameters.default(workspaceContext: workspaceContext, buildRequestContext: buildRequestContext, parameters: buildParams)
platformBuildParameters.append(PlatformBuildParameters(buildParams: buildParams, specializationParams: specializationParams))

if runDestination.platform == hostOS && runDestination.sdkVariant == matchingSDK.defaultVariant?.name {
if platform.name == hostOS && sdkVariant == matchingSDK.defaultVariant?.name {
hostBuildParameters = platformBuildParameters.last
}
}
Expand Down Expand Up @@ -594,14 +603,14 @@ extension SpecializationParameters {
for platformParams in platformBuildParametersForIndex {
// Before forming all new settings for this platform, do a fast check using `SUPPORTED_PLATFORMS` of `unconfiguredSettings`.
// This significantly cuts down the work that this function is doing.
if platformParams.buildParams.activeRunDestination?.sdkVariant == MacCatalystInfo.sdkVariantName {
if case let .toolchainSDK(_, _, sdkVariant: sdkVariant) = platformParams.buildParams.activeRunDestination?.buildTarget, sdkVariant == MacCatalystInfo.sdkVariantName {
// macCatalyst has various special rules, check it by forming new settings normally, below.
// Carve out once small exception for host tools, which should never build for Catalyst.
if let standardTarget = target as? StandardTarget, ProductTypeIdentifier(standardTarget.productTypeIdentifier).isHostBuildTool {
continue
}
} else {
if let platformName = platformParams.buildParams.activeRunDestination?.platform, unconfiguredSupportedPlatforms.count > 0 {
if case let .toolchainSDK(platform: platformName, _, _) = platformParams.buildParams.activeRunDestination?.buildTarget, unconfiguredSupportedPlatforms.count > 0 {
guard unconfiguredSupportedPlatforms.contains(platformName) else { continue }
}
}
Expand Down Expand Up @@ -649,10 +658,10 @@ extension SpecializationParameters {
guard let targetPlatform = settings.platform else {
return false
}
if targetPlatform.name != runDestination.platform {
if case let .toolchainSDK(platform: platform, _, _) = runDestination.buildTarget, targetPlatform.name != platform {
return false
}
if settings.sdkVariant?.name != runDestination.sdkVariant {
if case let .toolchainSDK(_, _, sdkVariant: sdkVariant) = runDestination.buildTarget, settings.sdkVariant?.name != sdkVariant {
return false
}

Expand Down Expand Up @@ -824,7 +833,7 @@ extension SpecializationParameters {
imposedSupportedPlatforms = supportedPlatforms

let hostPlatform = settings.globalScope.evaluate(BuiltinMacros.HOST_PLATFORM)
let runDestinationPlatform = buildRequest.parameters.activeRunDestination?.platform
let runDestinationPlatform = if case let .toolchainSDK(platform: platform, _, _) = buildRequest.parameters.activeRunDestination?.buildTarget { platform } else { Optional<String>.none }
let supportedPlatformsWithoutSimulators = Set(supportedPlatforms.compactMap { self.workspaceContext.core.platformRegistry.lookup(name: $0) }.filter { !$0.isSimulator }.map { $0.name })

// If the given specialization is unsupported, we still need to impose a platform.
Expand Down
6 changes: 6 additions & 0 deletions Sources/SWBCore/Extensions/PlatformInfoExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public protocol PlatformInfoExtension: Sendable {
func additionalPlatforms(context: any PlatformInfoExtensionAdditionalPlatformsContext) throws -> [(path: Path, data: [String: PropertyListItem])]

func adjustPlatformSDKSearchPaths(platformName: String, platformPath: Path, sdkSearchPaths: inout [Path])

func platformName(triple: LLVMTriple) -> String?
}

extension PlatformInfoExtension {
Expand Down Expand Up @@ -64,6 +66,10 @@ extension PlatformInfoExtension {

public func adjustPlatformSDKSearchPaths(platformName: String, platformPath: Path, sdkSearchPaths: inout [Path]) {
}

public func platformName(triple: LLVMTriple) -> String? {
return nil
}
}

public protocol PlatformInfoExtensionAdditionalPlatformsContext: Sendable {
Expand Down
Loading
Loading