Skip to content

Merge release/6.2 into main #650

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jul 11, 2025
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
3 changes: 3 additions & 0 deletions Sources/SWBApplePlatform/Specs/MetalCompiler.xcspec
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@
Metal30,
Metal31,
Metal32,
Metal40,
);
Category = BuildOptions;
},
Expand All @@ -272,6 +273,7 @@
Metal30,
Metal31,
Metal32,
Metal40,
);
CommandLineArgs = {
UseDeploymentTarget = ( );
Expand All @@ -286,6 +288,7 @@
Metal30 = ( "-std=metal3.0", );
Metal31 = ( "-std=metal3.1", );
Metal32 = ( "-std=metal3.2", );
Metal40 = ( "-std=metal4.0", );
};
},
{
Expand Down
1 change: 1 addition & 0 deletions Sources/SWBApplePlatform/Specs/MetalLinker.xcspec
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
Metal30 = ( "-std=metal3.0", );
Metal31 = ( "-std=metal3.1", );
Metal32 = ( "-std=metal3.2", );
Metal40 = ( "-std=metal4.0", );
};
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@
"[MTL_LANGUAGE_REVISION]-description-[Metal31]" = "Metal 3.1";
"[MTL_LANGUAGE_REVISION]-value-[Metal32]" = "Metal 3.2";
"[MTL_LANGUAGE_REVISION]-description-[Metal32]" = "Metal 3.2";
"[MTL_LANGUAGE_REVISION]-value-[Metal40]" = "Metal 4.0";
"[MTL_LANGUAGE_REVISION]-description-[Metal40]" = "Metal 4.0";

"[MTL_ENABLE_DEBUG_INFO]-name" = "Produce Debugging Information";
"[MTL_ENABLE_DEBUG_INFO]-description" = "Debugging information is required for shader debugging and profiling.";
Expand Down
6 changes: 6 additions & 0 deletions Sources/SWBApplePlatform/Specs/macOSCoreBuildSystem.xcspec
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
DefaultValue = "";
Category = "Deployment";
},
{ Name = "REGISTER_APP_GROUPS";
Type = Boolean;
DefaultValue = NO;
Category = "Code Signing";
Description = "Register app groups in profiles.";
},
);
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
Category = "Deployment";
Description = "Path to a file specifying additional requirements for a product archive.";
},
{ Name = "REGISTER_APP_GROUPS";
Type = Boolean;
DefaultValue = NO;
Category = "Code Signing";
Description = "Register app groups in profiles.";
},
);
}
)
36 changes: 34 additions & 2 deletions Sources/SWBCore/PlatformRegistry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,12 @@ public final class Platform: Sendable {
/// Minimum OS version for Swift-in-the-OS support. If this is `nil`, the platform does not support Swift-in-the-OS at all.
fileprivate(set) var minimumOSForSwiftInTheOS: Version? = nil

/// Minimum OS version for built-in Swift concurrency support. If this is `nil`, the platform does not support Swift concurrency at all.
/// Minimum OS version for Swift concurrency (Swift 5.5). If this is `nil`, the platform does not support Swift concurrency at all.
fileprivate(set) var minimumOSForSwiftConcurrency: Version? = nil

/// Minimum OS version for Span in the standard library (Swift 6.2). If this is `nil`, Span, MutableSpan, and related types are not available.
fileprivate(set) var minimumOSForSwiftSpan: Version? = nil

/// The canonical name of the public SDK for this platform.
/// - remark: This does not mean that this SDK exists, just that this is its canonical name if it does exist.
@_spi(Testing) public let sdkCanonicalName: String?
Expand Down Expand Up @@ -244,6 +247,11 @@ extension Platform {
return self.minimumOSForSwiftConcurrency ?? self.correspondingDevicePlatform?.minimumOSForSwiftConcurrency ?? nil
}

/// Determines the deployment version to use for Swift Span support.
fileprivate func swiftOSSpanVersion(_ deploymentTarget: StringMacroDeclaration) -> Version? {
return self.minimumOSForSwiftSpan ?? self.correspondingDevicePlatform?.minimumOSForSwiftSpan ?? nil
}

/// Determines if the platform supports Swift in the OS.
public func supportsSwiftInTheOS(_ scope: MacroEvaluationScope, forceNextMajorVersion: Bool = false, considerTargetDeviceOSVersion: Bool = true) -> Bool {
guard let deploymentTarget = self.deploymentTargetMacro else { return false }
Expand All @@ -265,7 +273,7 @@ extension Platform {
return version >= minimumSwiftInTheOSVersion
}

/// Determines if the platform natively supports Swift concurrency. If `false`, then the Swift back-compat concurrency libs needs to be copied into the app/framework's bundle.
/// Determines if the platform natively supports Swift concurrency. If `false`, then the Swift concurrency back-compat concurrency libs needs to be copied into the app/framework's bundle.
public func supportsSwiftConcurrencyNatively(_ scope: MacroEvaluationScope, forceNextMajorVersion: Bool = false, considerTargetDeviceOSVersion: Bool = true) -> Bool? {
guard let deploymentTarget = self.deploymentTargetMacro else { return false }

Expand All @@ -287,6 +295,29 @@ extension Platform {

return version >= minimumSwiftConcurrencyVersion
}

/// Determines if the platform natively supports Swift 6.2's Span type. If `false`, then the Swift Span back-compat lib needs to be copied into the app/framework's bundle.
public func supportsSwiftSpanNatively(_ scope: MacroEvaluationScope, forceNextMajorVersion: Bool, considerTargetDeviceOSVersion: Bool) -> Bool? {
guard let deploymentTarget = self.deploymentTargetMacro else { return false }

// If we have target device info and its platform matches the build platform, compare the device OS version
let targetDeviceVersion: Version?
if considerTargetDeviceOSVersion && scope.evaluate(BuiltinMacros.TARGET_DEVICE_PLATFORM_NAME) == self.name {
targetDeviceVersion = try? Version(scope.evaluate(BuiltinMacros.TARGET_DEVICE_OS_VERSION))
} else {
targetDeviceVersion = nil
}

// Otherwise fall back to comparing the minimum deployment target
let deploymentTargetVersion = try? Version(scope.evaluate(deploymentTarget))

guard let version = targetDeviceVersion ?? deploymentTargetVersion else { return false }

// Return `nil` here as there is no metadata for the platform to allow downstream clients to be aware of this.
guard let minimumSwiftSpanVersion = swiftOSSpanVersion(deploymentTarget) else { return nil }

return version >= minimumSwiftSpanVersion
}
}

extension Platform: CustomStringConvertible {
Expand Down Expand Up @@ -633,6 +664,7 @@ public final class PlatformRegistry {
if let variant = platform.defaultSDKVariant {
platform.minimumOSForSwiftInTheOS = variant.minimumOSForSwiftInTheOS
platform.minimumOSForSwiftConcurrency = variant.minimumOSForSwiftConcurrency
platform.minimumOSForSwiftSpan = variant.minimumOSForSwiftSpan
}
}

Expand Down
14 changes: 9 additions & 5 deletions Sources/SWBCore/SDKRegistry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,12 @@ public final class SDKVariant: PlatformInfoProvider, Sendable {
/// Minimum OS version for Swift-in-the-OS support. If this is `nil`, the platform does not support Swift-in-the-OS at all.
public let minimumOSForSwiftInTheOS: Version?

/// Minimum OS version for built-in Swift concurrency support. If this is `nil`, the platform does not support Swift concurrency at all.
/// Minimum OS version for built-in Swift concurrency support (Swift 5.5). If this is `nil`, the platform does not support Swift concurrency at all.
public let minimumOSForSwiftConcurrency: Version?

/// Minimum OS version for built-in Swift Span support (Swift 6.2). If this is `nil`, the platform does not support Swift Span at all.
public let minimumOSForSwiftSpan: Version?

/// The path prefix under which all built content produced by this SDK variant should be installed, relative to the system root.
///
/// Empty string if content should be installed directly into the system root (default).
Expand Down Expand Up @@ -392,9 +395,10 @@ public final class SDKVariant: PlatformInfoProvider, Sendable {

self.clangRuntimeLibraryPlatformName = supportedTargetDict["ClangRuntimeLibraryPlatformName"]?.stringValue ?? Self.fallbackClangRuntimeLibraryPlatformName(variantName: name)

let (os, concurrency) = Self.fallbackSwiftVersions(variantName: name)
let (os, concurrency, span) = Self.fallbackSwiftVersions(variantName: name)
self.minimumOSForSwiftInTheOS = try (supportedTargetDict["SwiftOSRuntimeMinimumDeploymentTarget"]?.stringValue ?? os).map { try Version($0) }
self.minimumOSForSwiftConcurrency = try (supportedTargetDict["SwiftConcurrencyMinimumDeploymentTarget"]?.stringValue ?? concurrency).map { try Version($0) }
self.minimumOSForSwiftSpan = try (supportedTargetDict["SwiftSpanMinimumDeploymentTarget"]?.stringValue ?? span).map { try Version($0) }

self.systemPrefix = supportedTargetDict["SystemPrefix"]?.stringValue ?? {
switch name {
Expand Down Expand Up @@ -445,12 +449,12 @@ public final class SDKVariant: PlatformInfoProvider, Sendable {
}
}

private static func fallbackSwiftVersions(variantName name: String) -> (String?, String?) {
private static func fallbackSwiftVersions(variantName name: String) -> (os: String?, concurrency: String?, span: String?) {
switch name {
case "macos", "macosx":
return ("10.14.4", "12.0")
return ("10.14.4", "12.0", "26.0")
default:
return (nil, nil)
return (nil, nil, "26.0")
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/SWBCore/SWBFeatureFlag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,5 @@ public enum SWBFeatureFlag {

public static let enableCacheMetricsLogs = SWBFeatureFlagProperty("EnableCacheMetricsLogs", defaultValue: false)

public static let enableAppSandboxConflictingValuesEmitsWarning = SWBFeatureFlagProperty("AppSandboxConflictingValuesEmitsWarning", defaultValue: false)
public static let enableAppSandboxConflictingValuesEmitsWarning = SWBFeatureFlagProperty("AppSandboxConflictingValuesEmitsWarning", defaultValue: true)
}
2 changes: 2 additions & 0 deletions Sources/SWBCore/Settings/BuiltinMacros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,7 @@ public final class BuiltinMacros {
public static let DISABLE_INFOPLIST_PLATFORM_PROCESSING = BuiltinMacros.declareBooleanMacro("DISABLE_INFOPLIST_PLATFORM_PROCESSING")
public static let DISABLE_MANUAL_TARGET_ORDER_BUILD_WARNING = BuiltinMacros.declareBooleanMacro("DISABLE_MANUAL_TARGET_ORDER_BUILD_WARNING")
public static let DISABLE_STALE_FILE_REMOVAL = BuiltinMacros.declareBooleanMacro("DISABLE_STALE_FILE_REMOVAL")
public static let DISABLE_SWIFT_SPAN_COMPATIBILITY_RPATH = BuiltinMacros.declareBooleanMacro("DISABLE_SWIFT_SPAN_COMPATIBILITY_RPATH")
public static let DISABLE_TEST_HOST_PLATFORM_PROCESSING = BuiltinMacros.declareBooleanMacro("DISABLE_TEST_HOST_PLATFORM_PROCESSING")
public static let DISABLE_XCFRAMEWORK_SIGNATURE_VALIDATION = BuiltinMacros.declareBooleanMacro("DISABLE_XCFRAMEWORK_SIGNATURE_VALIDATION")
public static let DONT_CREATE_BUILT_PRODUCTS_DIR_SYMLINKS = BuiltinMacros.declareBooleanMacro("DONT_CREATE_BUILT_PRODUCTS_DIR_SYMLINKS")
Expand Down Expand Up @@ -1620,6 +1621,7 @@ public final class BuiltinMacros {
DISABLE_INFOPLIST_PLATFORM_PROCESSING,
DISABLE_MANUAL_TARGET_ORDER_BUILD_WARNING,
DISABLE_STALE_FILE_REMOVAL,
DISABLE_SWIFT_SPAN_COMPATIBILITY_RPATH,
DISABLE_TEST_HOST_PLATFORM_PROCESSING,
DISABLE_XCFRAMEWORK_SIGNATURE_VALIDATION,
DOCC_ARCHIVE_PATH,
Expand Down
5 changes: 5 additions & 0 deletions Sources/SWBCore/Settings/Settings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ fileprivate struct PreOverridesSettings {
table.push(BuiltinMacros.LM_SKIP_METADATA_EXTRACTION, BuiltinMacros.namespace.parseString("YES"))
}

// This is a hack to prevent Span back deployment from causing excessive test churn when using an older Xcode in Swift CI.
if core.xcodeProductBuildVersion <= (try! ProductBuildVersion("17A1")) {
table.push(BuiltinMacros.DISABLE_SWIFT_SPAN_COMPATIBILITY_RPATH, BuiltinMacros.namespace.parseString("YES"))
}

// Add the "calculated" settings.
addCalculatedUniversalDefaults(&table)

Expand Down
15 changes: 12 additions & 3 deletions Sources/SWBCore/SpecImplementations/Tools/LinkerTools.swift
Original file line number Diff line number Diff line change
Expand Up @@ -284,11 +284,20 @@ public final class LdLinkerSpec : GenericLinkerSpec, SpecIdentifierType, @unchec
// And, if the deployment target does not support Swift Concurrency natively, then the rpath needs to be added as well so that the shim library can find the real implementation. Note that we assume `true` in the case where `supportsSwiftInTheOS` is `nil` as we don't have the platform data to make the correct choice; so fallback to existing behavior.
// The all above discussion is only relevant for platforms that support Swift in the OS.
let supportsSwiftConcurrencyNatively = cbc.producer.platform?.supportsSwiftConcurrencyNatively(cbc.scope, forceNextMajorVersion: false, considerTargetDeviceOSVersion: false) ?? true
let supportsSwiftSpanNatively = cbc.producer.platform?.supportsSwiftSpanNatively(cbc.scope, forceNextMajorVersion: false, considerTargetDeviceOSVersion: false) ?? true
let shouldEmitRPathForSwiftConcurrency = UserDefaults.allowRuntimeSearchPathAdditionForSwiftConcurrency && !supportsSwiftConcurrencyNatively
if (cbc.producer.platform?.supportsSwiftInTheOS(cbc.scope, forceNextMajorVersion: true, considerTargetDeviceOSVersion: false) != true || cbc.producer.toolchains.usesSwiftOpenSourceToolchain || shouldEmitRPathForSwiftConcurrency) && isUsingSwift && cbc.producer.platform?.minimumOSForSwiftInTheOS != nil {
// NOTE: For swift.org toolchains, this is fine as `DYLD_LIBRARY_PATH` is used to override these settings.
let shouldEmitRPathForSwiftSpan = !cbc.scope.evaluate(BuiltinMacros.DISABLE_SWIFT_SPAN_COMPATIBILITY_RPATH) && !supportsSwiftSpanNatively
if (
cbc.producer.platform?.supportsSwiftInTheOS(cbc.scope, forceNextMajorVersion: true, considerTargetDeviceOSVersion: false) != true ||
cbc.producer.toolchains.usesSwiftOpenSourceToolchain ||
shouldEmitRPathForSwiftConcurrency ||
shouldEmitRPathForSwiftSpan
)
&& isUsingSwift
&& cbc.producer.platform?.minimumOSForSwiftInTheOS != nil {
// NOTE: For swift.org toolchains, this is fine as `DYLD_LIBRARY_PATH` is used to override these settings.
let swiftABIVersion = await (cbc.producer.swiftCompilerSpec.discoveredCommandLineToolSpecInfo(cbc.producer, cbc.scope, delegate) as? DiscoveredSwiftCompilerToolSpecInfo)?.swiftABIVersion
runpathSearchPaths.insert( swiftABIVersion.flatMap { "/usr/lib/swift-\($0)" } ?? "/usr/lib/swift", at: 0)
runpathSearchPaths.insert( swiftABIVersion.flatMap { "/usr/lib/swift-\($0)" } ?? "/usr/lib/swift", at: 0)
}

return runpathSearchPaths
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public final class SwiftStdLibToolSpec : GenericCommandLineToolSpec, SpecIdentif
}

/// Construct a new task to run the Swift standard library tool.
public func constructSwiftStdLibraryToolTask(_ cbc:CommandBuildContext, _ delegate: any TaskGenerationDelegate, foldersToScan: MacroStringListExpression?, filterForSwiftOS: Bool, backDeploySwiftConcurrency: Bool) async {
public func constructSwiftStdLibraryToolTask(_ cbc:CommandBuildContext, _ delegate: any TaskGenerationDelegate, foldersToScan: MacroStringListExpression?, filterForSwiftOS: Bool, backDeploySwiftConcurrency: Bool, backDeploySwiftSpan: Bool) async {
precondition(cbc.outputs.isEmpty, "Unexpected output paths \(cbc.outputs.map { "'\($0.str)'" }) passed to \(type(of: self)).")

let input = cbc.input
Expand Down Expand Up @@ -86,6 +86,10 @@ public final class SwiftStdLibToolSpec : GenericCommandLineToolSpec, SpecIdentif
commandLine.append("--back-deploy-swift-concurrency")
}

if backDeploySwiftSpan {
commandLine.append("--back-deploy-swift-span")
}

let outputs = [delegate.createVirtualNode("CopySwiftStdlib \(wrapperPathString.str)")]

delegate.createTask(type: self, dependencyData: .dependencyInfo(dependencyInfoFilePath), ruleInfo: ruleInfo, commandLine: commandLine, environment: EnvironmentBindings(environment.map { ($0, $1) }), workingDirectory: cbc.producer.defaultWorkingDirectory, inputs: [ delegate.createNode(input.absolutePath) ], outputs: outputs, mustPrecede: [], action: action, execDescription: resolveExecutionDescription(cbc, delegate, lookup: lookup), enableSandboxing: enableSandboxing)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,13 @@ final class SwiftStandardLibrariesTaskProducer: PhasedTaskProducer, TaskProducer
let supportsConcurrencyNatively = context.platform?.supportsSwiftConcurrencyNatively(scope)
let backDeploySwiftConcurrency = supportsConcurrencyNatively != nil && supportsConcurrencyNatively != true

let supportsSpanNatively = context.platform?.supportsSwiftSpanNatively(scope, forceNextMajorVersion: false, considerTargetDeviceOSVersion: true)
let backDeploySwiftSpan = supportsSpanNatively != nil && supportsSpanNatively != true

let cbc = CommandBuildContext(producer: context, scope: scope, inputs: [ input ])
let foldersToScanExpr: MacroStringListExpression? = foldersToScan.count > 0 ? scope.namespace.parseLiteralStringList(foldersToScan): nil
await appendGeneratedTasks(&tasks) { delegate in
await context.swiftStdlibToolSpec.constructSwiftStdLibraryToolTask(cbc, delegate, foldersToScan: foldersToScanExpr, filterForSwiftOS: filterForSwiftOS, backDeploySwiftConcurrency: backDeploySwiftConcurrency)
await context.swiftStdlibToolSpec.constructSwiftStdLibraryToolTask(cbc, delegate, foldersToScan: foldersToScanExpr, filterForSwiftOS: filterForSwiftOS, backDeploySwiftConcurrency: backDeploySwiftConcurrency, backDeploySwiftSpan: backDeploySwiftSpan)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,18 @@ public final class EmbedSwiftStdLibTaskAction: TaskAction {
// If true, then the Swift concurrency dylibs should be copied into the app/framework's bundles.
var backDeploySwiftConcurrency = false

// If true, then the Swift Span dylibs should be copied into the app/framework's bundles.
var backDeploySwiftSpan = false

// The allowed list of libraries that should *not* be filtered when `filterForSwiftOS=true`.
let allowedLibsForSwiftOS = ["libswiftXCTest" ]

// The allowed list of libraries that should *not* be filtered when `backDeploySwiftConcurrency=true`.
let allowedLibsForSwiftConcurrency = ["libswift_Concurrency"]

// The allowed list of libraries that should *not* be filtered when `backDeploySwiftSpan=true`.
let allowedLibsForSwiftSpan = ["libswiftCompatibilitySpan"]

func absolutePath(_ path: Path) -> Path {
return path.isAbsolute ? path : task.workingDirectory.join(path)
}
Expand Down Expand Up @@ -207,7 +213,7 @@ public final class EmbedSwiftStdLibTaskAction: TaskAction {

func effectiveSourceDirectories(_ toolchainsDirs: OrderedSet<Path>, platform: String) -> [Path] {
// FIXME: Maybe these should be defined within the toolchains or we could simply scan the toolchain directory as well.
let swiftBackdeploymentDirs = ["usr/lib/swift-5.0", "usr/lib/swift-5.5"]
let swiftBackdeploymentDirs = ["usr/lib/swift-5.0", "usr/lib/swift-5.5", "usr/lib/swift-6.2"]

var dirs = [Path]()
for dir in toolchainsDirs {
Expand Down Expand Up @@ -369,6 +375,9 @@ public final class EmbedSwiftStdLibTaskAction: TaskAction {
case "--back-deploy-swift-concurrency":
self.backDeploySwiftConcurrency = true

case "--back-deploy-swift-span":
self.backDeploySwiftSpan = true

default:
throw StubError.error("unrecognized argument: \(arg)")
}
Expand Down Expand Up @@ -788,6 +797,9 @@ public final class EmbedSwiftStdLibTaskAction: TaskAction {
if backDeploySwiftConcurrency && allowedLibsForSwiftConcurrency.contains(item) {
shouldInclude = true
}
if backDeploySwiftSpan && allowedLibsForSwiftSpan.contains(item) {
shouldInclude = true
}

return shouldInclude
}
Expand Down
Loading