Skip to content
Draft
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
7 changes: 0 additions & 7 deletions Sources/SWBCore/PlatformRegistry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -546,13 +546,6 @@ public final class PlatformRegistry {
var defaultSettings: [String: PropertyListItem] = [:]
if case .plDict(let defaultSettingsItems)? = items["DefaultProperties"] {
defaultSettings = defaultSettingsItems

// Rev-lock: rdar://85769354 (Remove DEPLOYMENT_TARGET_CLANG_* properties from SDK)
for macroName in [
"DEPLOYMENT_TARGET_CLANG_ENV_NAME",
"DEPLOYMENT_TARGET_CLANG_FLAG_NAME",
"DEPLOYMENT_TARGET_CLANG_FLAG_PREFIX",
] { defaultSettings.removeValue(forKey: macroName) }
}

// Parse whether this is a deployment platform.
Expand Down
87 changes: 6 additions & 81 deletions Sources/SWBCore/SDKRegistry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ public final class SDKVariant: PlatformInfoProvider, Sendable {
self.validDeploymentTargets = validDeploymentTargets

// The recommended deployment target is the default deployment target for the platform, unless we've overridden to a more specific value.
self.recommendedDeploymentTarget = (try? Version(supportedTargetDict["RecommendedDeploymentTarget"]?.stringValue ?? Self.fallbackRecommendedDeploymentTarget(variantName: name) ?? "")) ?? defaultDeploymentTarget
self.recommendedDeploymentTarget = (try? Version(supportedTargetDict["RecommendedDeploymentTarget"]?.stringValue ?? "")) ?? defaultDeploymentTarget

self.llvmTargetTripleEnvironment = supportedTargetDict["LLVMTargetTripleEnvironment"]?.stringValue
self.llvmTargetTripleSys = supportedTargetDict["LLVMTargetTripleSys"]?.stringValue
Expand All @@ -398,90 +398,17 @@ public final class SDKVariant: PlatformInfoProvider, Sendable {
self.targetOSMacroName = nil
}

self.deviceFamilies = try DeviceFamilies(families: PropertyList.decode([DeviceFamily].self, from: supportedTargetDict["DeviceFamilies"] ?? Self.fallbackDeviceFamiliesData(variantName: name)))
self.deviceFamilies = try DeviceFamilies(families: PropertyList.decode([DeviceFamily].self, from: supportedTargetDict["DeviceFamilies"] ?? []))

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

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.minimumOSForSwiftInTheOS = try (supportedTargetDict["SwiftOSRuntimeMinimumDeploymentTarget"]?.stringValue).map { try Version($0) }
self.minimumOSForSwiftConcurrency = try (supportedTargetDict["SwiftConcurrencyMinimumDeploymentTarget"]?.stringValue).map { try Version($0) }
self.minimumOSForSwiftSpan = try (supportedTargetDict["SwiftSpanMinimumDeploymentTarget"]?.stringValue).map { try Version($0) }

self.systemPrefix = supportedTargetDict["SystemPrefix"]?.stringValue ?? ""
}

private static func fallbackDeviceFamiliesData(variantName name: String) throws -> PropertyListItem {
switch name {
case "macos", "macosx":
return .plArray([
.plDict([
"Name": .plString("mac"),
"DisplayName": .plString("Mac"),
])
])
case MacCatalystInfo.sdkVariantName:
return .plArray([
.plDict([
"Identifier": .plInt(2),
"Name": .plString("pad"),
"DisplayName": .plString("iPad"),
]),
.plDict([
"Identifier": .plInt(6),
"Name": .plString("mac"),
"DisplayName": .plString("Mac"),
])
])
default:
// Other platforms don't have device families
return .plArray([])
}
}

private static func fallbackClangRuntimeLibraryPlatformName(variantName name: String) -> String? {
switch name {
case "macos", "macosx", MacCatalystInfo.sdkVariantName:
return "osx"
default:
return nil
}
}

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

private static func fallbackRecommendedDeploymentTarget(variantName name: String) -> String? {
switch name {
// Late Summer 2019 aligned, except iOS which got one final 12.x update in Winter 2020, making this version set the last minor update series of the Fall 2018 aligned releases.
case "macos", "macosx":
return "10.14.6"
case "iphoneos", "iphonesimulator":
return "12.5"
case "appletvos", "appletvsimulator":
return "12.4"
case "watchos", "watchsimulator":
return "5.3"

// No Summer 2019 aligned versions since these were first introduced on or after Fall 2019, so simply use the minimum versions.
case "driverkit":
return "19.0"
case MacCatalystInfo.sdkVariantName:
return "13.1"
case "xros", "xrsimulator":
return "1.0"

// Fall back to the default deployment target, which is equal to the SDK version.
default:
return nil
}
}

/// Perform late binding of the build settings. This is a private function that may only be invoked once for any given SDK variant.
/// - Parameters:
/// - associatedTypesForKeysMatching: Passed to `MacroNamespace.parseTable` - refer there for more info.
Expand Down Expand Up @@ -761,14 +688,12 @@ public final class SDKRegistry: SDKRegistryLookup, CustomStringConvertible, Send
var defaultSettings: [String: PropertyListItem] = [:]
if case .plDict(let settingsItems)? = items["DefaultProperties"] {
defaultSettings = filteredSettings(settingsItems)
.filter { $0.key != "TEST_FRAMEWORK_DEVELOPER_VARIANT_SUBPATH" } // rdar://107954685 (Remove watchOS special case for testing framework paths)
}

// Parse the custom properties settings.
var overrideSettings: [String: PropertyListItem] = [:]
if case .plDict(let settingsItems)? = items["CustomProperties"] {
overrideSettings = filteredSettings(settingsItems)
.filter { !$0.key.hasPrefix("SWIFT_MODULE_ONLY_") } // Rev-lock: don't set SWIFT_MODULE_ONLY_ in SDKs
}

// Parse the Variants array and the SupportedTargets dictionary, then create the SDKVariant objects from them. Note that it is not guaranteed that any variant will have both sets of data, so we don't the presence of either one.
Expand Down
2 changes: 2 additions & 0 deletions Sources/SWBCore/Settings/BuiltinMacros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ public final class BuiltinMacros {
public static let HOST_PLATFORM = BuiltinMacros.declareStringMacro("HOST_PLATFORM")
public static let IOS_UNZIPPERED_TWIN_PREFIX_PATH = BuiltinMacros.declareStringMacro("IOS_UNZIPPERED_TWIN_PREFIX_PATH")
public static let IPHONEOS_DEPLOYMENT_TARGET = BuiltinMacros.declareStringMacro("IPHONEOS_DEPLOYMENT_TARGET")
public static let MACOS_UNZIPPERED_TWIN_PREFIX_PATH = BuiltinMacros.declareStringMacro("MACOS_UNZIPPERED_TWIN_PREFIX_PATH")
public static let MACOSX_DEPLOYMENT_TARGET = BuiltinMacros.declareStringMacro("MACOSX_DEPLOYMENT_TARGET")
public static let NATIVE_ARCH = BuiltinMacros.declareStringMacro("NATIVE_ARCH")
public static let NATIVE_ARCH_32_BIT = BuiltinMacros.declareStringMacro("NATIVE_ARCH_32_BIT")
Expand Down Expand Up @@ -1993,6 +1994,7 @@ public final class BuiltinMacros {
MACOS_CREATOR_ARG,
MACOS_TYPE,
MACOS_TYPE_ARG,
MACOS_UNZIPPERED_TWIN_PREFIX_PATH,
MAC_OS_X_PRODUCT_BUILD_VERSION,
MAC_OS_X_VERSION_ACTUAL,
MAC_OS_X_VERSION_MAJOR,
Expand Down
10 changes: 5 additions & 5 deletions Sources/SWBCore/Settings/Settings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2524,6 +2524,11 @@ private class SettingsBuilder: ProjectMatchLookup {
platformTable.push(BuiltinMacros.PLATFORM_DEVELOPER_USR_DIR, Static { BuiltinMacros.namespace.parseString("$(DEVELOPER_USR_DIR)") })
platformTable.push(BuiltinMacros.PLATFORM_DEVELOPER_BIN_DIR, Static { BuiltinMacros.namespace.parseString("$(DEVELOPER_BIN_DIR)") })
platformTable.push(BuiltinMacros.PLATFORM_DEVELOPER_SDK_DIR, Static { BuiltinMacros.namespace.parseString("$(DEVELOPER_SDK_DIR)") })

// Set twin prefix paths in macOS for Mac Catalyst.
platformTable.push(BuiltinMacros.MACOS_UNZIPPERED_TWIN_PREFIX_PATH, literal: "")
platformTable.push(BuiltinMacros.IOS_UNZIPPERED_TWIN_PREFIX_PATH, literal: "/System/iOSSupport")

} else {
platformTable.push(BuiltinMacros.PLATFORM_DEVELOPER_APPLICATIONS_DIR, literal: "\(platform.path.str)/Developer/Applications")
platformTable.push(BuiltinMacros.PLATFORM_DEVELOPER_TOOLS_DIR, literal: "\(platform.path.str)/Developer/Tools")
Expand Down Expand Up @@ -2585,11 +2590,6 @@ private class SettingsBuilder: ProjectMatchLookup {
sdkTable.pushContentsOf(defaultSettingsTable)
}

// Set IOS_UNZIPPERED_TWIN_PREFIX_PATH to the Mac Catalyst variant's prefix path, even for the macOS variant.
if let macCatalystVariant = sdk.variant(for: MacCatalystInfo.sdkVariantName) {
sdkTable.push(BuiltinMacros.IOS_UNZIPPERED_TWIN_PREFIX_PATH, literal: macCatalystVariant.systemPrefix)
}

// Add the settings provided by the SDK variant, if there is one.
if let variant {
// Late-bound by `SDKRegistry.loadExtendedInfo` and may be nil if an error (which will have already been reported) was encountered during loading.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1045,7 +1045,7 @@ fileprivate struct UnitTestBuildOperationTests: CoreBasedTests {

/// Test building an application and a UI test target for iOS for both the device and the simulator.
@Test(.requireSDKs(.iOS))
func uITestTarget_iOS() async throws {
func uiTestTarget_iOS() async throws {
// Creates and returns a tester for a given test.
func makeTester(_ tmpDir: Path) async throws -> BuildOperationTester {
let testWorkspace = try await TestWorkspace(
Expand Down
7 changes: 6 additions & 1 deletion Tests/SWBCoreTests/SDKRegistryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,12 @@ import SWBMacro
"CanonicalName": "macosbork",
"IsBaseSDK": "YES",
"SupportedTargets": [
"iosmac": [] as PropertyListItem
"iosmac": [
"DeviceFamilies": [
["DisplayName": "iPad", "Identifier": "2", "Name": "pad"],
["DisplayName": "Mac", "Identifier": "6", "Name": "mac"],
]
] as PropertyListItem
]
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ fileprivate struct SwiftTaskConstructionTests: CoreBasedTests {
}
}

@Test(.requireSDKs(.macOS))
@Test(.requireSDKs(.macOS), .requireXcode26())
func swiftAppBasics_preSwiftOS() async throws {
try await _testSwiftAppBasics(deploymentTargetVersion: "10.14.0", shouldEmitSwiftRPath: true, shouldFilterSwiftLibs: false, shouldBackDeploySwiftConcurrency: true, shouldBackDeploySwiftSpan: true)
}

@Test(.requireSDKs(.macOS))
@Test(.requireSDKs(.macOS), .requireXcode26())
func swiftAppBasics_postSwiftOS() async throws {
try await _testSwiftAppBasics(deploymentTargetVersion: "12.0", shouldEmitSwiftRPath: true, shouldFilterSwiftLibs: true, shouldBackDeploySwiftConcurrency: false, shouldBackDeploySwiftSpan: true, missingSpanCompatibilitySuppressesRPath: true)
}
Expand All @@ -84,22 +84,22 @@ fileprivate struct SwiftTaskConstructionTests: CoreBasedTests {
try await _testSwiftAppBasics(deploymentTargetVersion: "26.0", shouldEmitSwiftRPath: false, shouldFilterSwiftLibs: true, shouldBackDeploySwiftConcurrency: false, shouldBackDeploySwiftSpan: false)
}

@Test(.requireSDKs(.macOS))
@Test(.requireSDKs(.macOS), .requireXcode26())
func swiftAppBasics_preSwiftOSDeploymentTarget_postSwiftOSTargetDevice() async throws {
try await _testSwiftAppBasics(deploymentTargetVersion: "10.14.0", targetDeviceOSVersion: "11.0", targetDevicePlatformName: "macosx", shouldEmitSwiftRPath: true, shouldFilterSwiftLibs: true, shouldBackDeploySwiftConcurrency: true, shouldBackDeploySwiftSpan: true)
}

@Test(.requireSDKs(.macOS))
@Test(.requireSDKs(.macOS), .requireXcode26())
func swiftAppBasics_preSwiftOSDeploymentTarget_postSwiftOSTargetDevice_mixedPlatform() async throws {
try await _testSwiftAppBasics(deploymentTargetVersion: "10.14.0", targetDeviceOSVersion: "14.0", targetDevicePlatformName: "iphoneos", shouldEmitSwiftRPath: true, shouldFilterSwiftLibs: false, shouldBackDeploySwiftConcurrency: true, shouldBackDeploySwiftSpan: true)
}

@Test(.requireSDKs(.macOS))
@Test(.requireSDKs(.macOS), .requireXcode26())
func swiftAppBasics_postSwiftOSDeploymentTarget_preSwiftConcurrencySupportedNatively() async throws {
try await _testSwiftAppBasics(deploymentTargetVersion: "11.0", shouldEmitSwiftRPath: true, shouldFilterSwiftLibs: true, shouldBackDeploySwiftConcurrency: true, shouldBackDeploySwiftSpan: true)
}

@Test(.requireSDKs(.macOS), .userDefaults(["AllowRuntimeSearchPathAdditionForSwiftConcurrency": "0"]))
@Test(.requireSDKs(.macOS), .requireXcode26(), .userDefaults(["AllowRuntimeSearchPathAdditionForSwiftConcurrency": "0"]))
func swiftAppBasics_postSwiftOSDeploymentTarget_preSwiftConcurrencySupportedNatively_DisallowRpathInjection() async throws {
try await _testSwiftAppBasics(deploymentTargetVersion: "11.0", shouldEmitSwiftRPath:true, shouldFilterSwiftLibs: true, shouldBackDeploySwiftConcurrency: true, shouldBackDeploySwiftSpan: true,
missingSpanCompatibilitySuppressesRPath: true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2800,8 +2800,8 @@ fileprivate struct UnitTestTaskConstructionTests: CoreBasedTests {
/// Test task construction for a UI test target for iOS. Both debug and install builds are tested for the device, and a debug build is tested for the simulator.
///
/// This test is primarily intended to validate that building for iOS works, to check that the different bundle packaging for iOS is being handled, and to check some ways in which building for iOS differs from building for macOS. The corresponding macOS test dives deeper into checking details of the tasks.
@Test(.requireSDKs(.macOS, .iOS))
func uITestTarget_iOS() async throws {
@Test(.requireSDKs(.macOS, .iOS), .requireXcode26())
func uiTestTarget_iOS() async throws {
let testProject = try await TestProject(
"aProject",
groupTree: TestGroup(
Expand Down