Skip to content

Merge main into release/6.2 #532

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 19 commits into from
May 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
769b50e
Added a new test of the SwiftBuildMessage stream to ensure we get the…
cwakamo May 15, 2025
d9d64a6
Fix quadratic behavior when GenericOutputParser is written to many ti…
owenv May 19, 2025
e7543d1
Read hardcoded deployment targets list from features.json instead
jakepetroules May 15, 2025
8eecb15
Merge pull request #511 from cwakamo/dev/add-multiple-target-test
cwakamo May 20, 2025
64d201f
Merge pull request #514 from swiftlang/owenv/genericparserperf
owenv May 20, 2025
8e71bde
Add support for building Swift on Android targets
jakepetroules May 20, 2025
9808dc1
Ensure swift jobs with the same command line but different dependenci…
owenv May 22, 2025
bd0d3ee
Merge pull request #520 from swiftlang/owenv/dep-dedupe
owenv May 22, 2025
6d90d36
Document setting for allowing use of explicit modules with c++ interop
owenv May 22, 2025
f8c09ea
PlannedSwiftDriverJob - fix deserializer count
owenv May 22, 2025
af374b5
Generalize the Swift version regex
bnbarham May 21, 2025
d8316bd
Merge pull request #521 from swiftlang/owenv/cxx-setting
owenv May 22, 2025
054f230
Merge pull request #522 from swiftlang/owenv/fix-count
owenv May 22, 2025
f38a04f
Implement __SKIP_BUILD setting to prune test runners from builds for …
owenv May 26, 2025
c525532
Mark explicitBuildDescriptionID test as flaky
owenv May 27, 2025
3d14acc
Merge pull request #525 from swiftlang/owenv/skip
owenv May 27, 2025
f69eff2
Merge pull request #529 from swiftlang/owenv/flaky-test
owenv May 27, 2025
69d5522
Revert "Document setting for allowing use of explicit modules with c+…
owenv May 27, 2025
85f272c
Merge pull request #531 from swiftlang/pr/ovoorhees/revert
owenv May 28, 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
8 changes: 4 additions & 4 deletions Sources/SWBAndroidPlatform/AndroidSDK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ struct AndroidSDK: Sendable {
}

struct LLVMTriple: Codable {
let arch: String
let vendor: String
let system: String
let environment: String
var arch: String
var vendor: String
var system: String
var environment: String

var description: String {
"\(arch)-\(vendor)-\(system)-\(environment)"
Expand Down
37 changes: 32 additions & 5 deletions Sources/SWBAndroidPlatform/Plugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@ struct AndroidEnvironmentExtension: EnvironmentExtension {
}

struct AndroidPlatformExtension: PlatformInfoExtension {
func knownDeploymentTargetMacroNames() -> Set<String> {
["ANDROID_DEPLOYMENT_TARGET"]
}

func additionalPlatforms(context: any PlatformInfoExtensionAdditionalPlatformsContext) throws -> [(path: Path, data: [String: PropertyListItem])] {
[
(.root, [
Expand Down Expand Up @@ -120,6 +116,37 @@ struct AndroidSDKRegistryExtension: SDKRegistryExtension {
return []
}

let allPossibleTriples = abis.values.flatMap { abi in
(max(deploymentTargetRange.min, abi.min_os_version)...deploymentTargetRange.max).map { deploymentTarget in
var triple = abi.llvm_triple
triple.vendor = "unknown" // Android NDK uses "none", Swift SDKs use "unknown"
triple.environment += "\(deploymentTarget)"
return triple
}
}.map(\.description)

let androidSwiftSDKs = (try? SwiftSDK.findSDKs(
targetTriples: allPossibleTriples,
fs: context.fs,
hostOperatingSystem: context.hostOperatingSystem
)) ?? []

let swiftSettings: [String: PropertyListItem]
// FIXME: We need a way to narrow down the list, possibly by passing down a Swift SDK identifier from SwiftPM
// The resource path should be the same for all triples in an Android Swift SDK
if let androidSwiftSDK = androidSwiftSDKs.only, let swiftResourceDir = Set(androidSwiftSDK.targetTriples.values.map { tripleProperties in androidSwiftSDK.path.join(tripleProperties.swiftResourcesPath) }).only {
swiftSettings = [
"SWIFT_LIBRARY_PATH": .plString(swiftResourceDir.join("android").str),
"SWIFT_RESOURCE_DIR": .plString(swiftResourceDir.str),
"SWIFT_TARGET_TRIPLE": .plString("$(CURRENT_ARCH)-unknown-$(SWIFT_PLATFORM_TARGET_PREFIX)$(LLVM_TARGET_TRIPLE_SUFFIX)"),
"LIBRARY_SEARCH_PATHS": "$(inherited) $(SWIFT_RESOURCE_DIR)/../$(__ANDROID_TRIPLE_$(CURRENT_ARCH))",
].merging(abis.map {
("__ANDROID_TRIPLE_\($0.value.llvm_triple.arch)", .plString($0.value.triple))
}, uniquingKeysWith: { _, new in new })
} else {
swiftSettings = [:]
}

return [(androidSdk.sysroot ?? .root, androidPlatform, [
"Type": .plString("SDK"),
"Version": .plString("0.0.0"),
Expand All @@ -133,7 +160,7 @@ struct AndroidSDKRegistryExtension: SDKRegistryExtension {
// FIXME: Make this configurable in a better way so we don't need to push build settings at the SDK definition level
"LLVM_TARGET_TRIPLE_OS_VERSION": .plString("linux"),
"LLVM_TARGET_TRIPLE_SUFFIX": .plString("-android$(ANDROID_DEPLOYMENT_TARGET)"),
]),
].merging(swiftSettings, uniquingKeysWith: { _, new in new })),
"SupportedTargets": .plDict([
"android": .plDict([
"Archs": .plArray(abis.map { .plString($0.value.llvm_triple.arch) }),
Expand Down
11 changes: 0 additions & 11 deletions Sources/SWBApplePlatform/Plugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,6 @@ struct XCStringsInputFileGroupingStrategyExtension: InputFileGroupingStrategyExt
}

struct ApplePlatformInfoExtension: PlatformInfoExtension {
func knownDeploymentTargetMacroNames() -> Set<String> {
[
"MACOSX_DEPLOYMENT_TARGET",
"IPHONEOS_DEPLOYMENT_TARGET",
"TVOS_DEPLOYMENT_TARGET",
"WATCHOS_DEPLOYMENT_TARGET",
"DRIVERKIT_DEPLOYMENT_TARGET",
"XROS_DEPLOYMENT_TARGET",
]
}

func preferredArchValue(for platformName: String) -> String? {
// FIXME: rdar://65011964 (Remove PLATFORM_PREFERRED_ARCH)
// Don't add values for any new platforms
Expand Down
3 changes: 2 additions & 1 deletion Sources/SWBBuildService/Messages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1440,7 +1440,8 @@ private struct AllExportedMacrosAndValuesMsg: MessageHandler {
let settings = try getSettings(for: session, workspaceContext: workspaceContext, requestContext: message.context, purpose: .build)

// Get the list of setting names and evaluated values. We use the same algorithm as is used to export settings to shell script build phases.
let exportedMacrosAndValues = computeScriptEnvironment(.shellScriptPhase, scope: settings.globalScope, settings: settings, workspaceContext: workspaceContext)
// We explicitly pass an empty set for `allDeploymentTargetMacroNames` because in this context we are exporting the list of known macros and not applying the special case to only exported a single deployment target like we do in shell scripts.
let exportedMacrosAndValues = computeScriptEnvironment(.shellScriptPhase, scope: settings.globalScope, settings: settings, workspaceContext: workspaceContext, allDeploymentTargetMacroNames: [])

return AllExportedMacrosAndValuesResponse(result: exportedMacrosAndValues)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/SWBBuildSystem/CleanOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ package final class CleanOperation: BuildSystemOperation, TargetDependencyResolv
delegate.targetPreparationStarted(self, configuredTarget: configuredTarget)
delegate.targetStarted(self, configuredTarget: configuredTarget)

let (executable, arguments, workingDirectory, environment) = constructCommandLine(for: configuredTarget.target as! SWBCore.ExternalTarget, action: "clean", settings: settings, workspaceContext: workspaceContext, scope: settings.globalScope)
let (executable, arguments, workingDirectory, environment) = constructCommandLine(for: configuredTarget.target as! SWBCore.ExternalTarget, action: "clean", settings: settings, workspaceContext: workspaceContext, scope: settings.globalScope, allDeploymentTargetMacroNames: [])
let commandLine = [executable] + arguments

let specLookupContext = SpecLookupCtxt(specRegistry: workspaceContext.core.specRegistry, platform: settings.platform)
Expand Down
6 changes: 0 additions & 6 deletions Sources/SWBCore/Extensions/PlatformInfoExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ public struct PlatformInfoExtensionPoint: ExtensionPoint, Sendable {
}

public protocol PlatformInfoExtension: Sendable {
func knownDeploymentTargetMacroNames() -> Set<String>

func preferredArchValue(for: String) -> String?

func additionalTestLibraryPaths(scope: MacroEvaluationScope, platform: Platform?, fs: any FSProxy) -> [Path]
Expand All @@ -40,10 +38,6 @@ public protocol PlatformInfoExtension: Sendable {
}

extension PlatformInfoExtension {
public func knownDeploymentTargetMacroNames() -> Set<String> {
[]
}

public func preferredArchValue(for: String) -> String? {
nil
}
Expand Down
28 changes: 15 additions & 13 deletions Sources/SWBCore/LibSwiftDriver/PlannedBuild.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ public struct SwiftDriverJob: Serializable, CustomDebugStringConvertible {
public let outputs: [Path]
/// The command line to execute for this job
public let commandLine: [SWBUtil.ByteString]
/// A signature which uniquely identifies the job.
public let signature: SWBUtil.ByteString
/// Cache keys for the swift-frontend invocation (one key per output producing input)
public let cacheKeys: [String]

Expand All @@ -103,15 +101,10 @@ public struct SwiftDriverJob: Serializable, CustomDebugStringConvertible {
self.cacheKeys = job.outputCacheKeys.reduce(into: [String]()) { result, key in
result.append(key.value)
}.sorted()
let md5 = InsecureHashContext()
for arg in commandLine {
md5.add(bytes: arg)
}
self.signature = md5.signature
}

public func serialize<T>(to serializer: T) where T : Serializer {
serializer.serializeAggregate(10) {
serializer.serializeAggregate(9) {
serializer.serialize(kind)
serializer.serialize(ruleInfoType)
serializer.serialize(moduleName)
Expand All @@ -120,13 +113,12 @@ public struct SwiftDriverJob: Serializable, CustomDebugStringConvertible {
serializer.serialize(outputs)
serializer.serialize(commandLine)
serializer.serialize(descriptionForLifecycle)
serializer.serialize(signature)
serializer.serialize(cacheKeys)
}
}

public init(from deserializer: any Deserializer) throws {
try deserializer.beginAggregate(10)
try deserializer.beginAggregate(9)
try self.kind = deserializer.deserialize()
try self.ruleInfoType = deserializer.deserialize()
try self.moduleName = deserializer.deserialize()
Expand All @@ -135,7 +127,6 @@ public struct SwiftDriverJob: Serializable, CustomDebugStringConvertible {
try self.outputs = deserializer.deserialize()
try self.commandLine = deserializer.deserialize()
try self.descriptionForLifecycle = deserializer.deserialize()
try self.signature = deserializer.deserialize()
try self.cacheKeys = deserializer.deserialize()
}

Expand Down Expand Up @@ -173,29 +164,40 @@ extension LibSwiftDriver {
public let dependencies: [JobKey]
/// Working directory for running this job
public let workingDirectory: Path
/// A signature which uniquely identifies this planned job.
public let signature: SWBUtil.ByteString

internal init(key: JobKey, driverJob: SwiftDriverJob, dependencies: [JobKey], workingDirectory: Path) {
self.key = key
self.driverJob = driverJob
self.dependencies = dependencies
self.workingDirectory = workingDirectory
let md5 = InsecureHashContext()
for arg in driverJob.commandLine {
md5.add(bytes: arg)
}
md5.add(string: workingDirectory.str)
md5.add(number: dependencies.hashValue)
self.signature = md5.signature
}

public func serialize<T>(to serializer: T) where T : Serializer {
serializer.serializeAggregate(4) {
serializer.serializeAggregate(5) {
serializer.serialize(key)
serializer.serialize(driverJob)
serializer.serialize(dependencies)
serializer.serialize(workingDirectory)
serializer.serialize(signature)
}
}

public init(from deserializer: any Deserializer) throws {
try deserializer.beginAggregate(4)
try deserializer.beginAggregate(5)
try key = deserializer.deserialize()
try driverJob = deserializer.deserialize()
try dependencies = deserializer.deserialize()
try workingDirectory = deserializer.deserialize()
try signature = deserializer.deserialize()
}

public func addingDependencies(_ newDependencies: [JobKey]) -> PlannedSwiftDriverJob {
Expand Down
45 changes: 0 additions & 45 deletions Sources/SWBCore/PlatformRegistry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,6 @@ public final class PlatformRegistry {
/// The map of platforms by name.
var platformsByName = Dictionary<String, Platform>()

/// The set of all known deployment target macro names, even if the platforms that use those settings are not installed.
private(set) var allDeploymentTargetMacroNames = Set<String>()

/// The default deployment targets for all installed platforms.
var defaultDeploymentTargets: [String: Version] {
Dictionary(uniqueKeysWithValues: Dictionary(grouping: platforms, by: { $0.defaultSDKVariant?.deploymentTargetSettingName })
Expand Down Expand Up @@ -353,46 +350,6 @@ public final class PlatformRegistry {
}
}

private func loadDeploymentTargetMacroNames() {
// We must have loaded the extended platform info before doing this,
// since deploymentTargetMacro is set on the Platform objects through there.
precondition(hasLoadedExtendedInfo)

// Set up allDeploymentTargetMacroNames in stages to detect issues.
// First we add all deployment targets from installed platforms, and emit a warning if multiple platforms declare that they use the same deployment target.
var platformsByDeploymentTarget = [String: Set<String>]()
for platform in platforms {
if let macroName = platform.deploymentTargetMacro?.name, !macroName.isEmpty {
allDeploymentTargetMacroNames.insert(macroName)

// Don't count simulator platforms separately, as a simulator platform always shares a deployment target with its corresponding device platform.
platformsByDeploymentTarget[macroName, default: Set<String>()].insert(platform.correspondingDevicePlatform?.name ?? platform.name)
}
}

// Now add in all deployment targets we know about. This is because clang also knows about these deployment targets intrinsically when they are passed as environment variables, so we sometimes need to work with them even if the platform which defines them is not installed.
@preconcurrency @PluginExtensionSystemActor func platformInfoExtensions() -> [any PlatformInfoExtensionPoint.ExtensionProtocol] {
delegate.pluginManager.extensions(of: PlatformInfoExtensionPoint.self)
}

for platformExtension in platformInfoExtensions() {
for knownDeploymentTargetMacroName in platformExtension.knownDeploymentTargetMacroNames() {
allDeploymentTargetMacroNames.insert(knownDeploymentTargetMacroName)
platformsByDeploymentTarget[knownDeploymentTargetMacroName] = nil
}
}

// For any macros left in the dictionary, emit a warning that it's a deployment target macro we didn't know about so we can add them to the list above in the future.
for macroName in platformsByDeploymentTarget.keys.sorted() {
guard let platformNames = platformsByDeploymentTarget[macroName], !platformNames.isEmpty else {
// This is a weird scenario - should we emit a warning here?
continue
}
let platformList: String = (platformNames.count > 1 ? "s: " : ": ") + platformNames.sorted().joined(separator: ", ")
delegate.warning("found previously-unknown deployment target macro '\(macroName)' declared by platform\(platformList)")
}
}

/// Register all platforms in the given directory.
private func registerPlatformsInDirectory(_ path: Path, _ fs: any FSProxy) async {
for item in (try? localFS.listdir(path))?.sorted(by: <) ?? [] {
Expand Down Expand Up @@ -690,8 +647,6 @@ public final class PlatformRegistry {
unregisterPlatform(platform)
}
}

loadDeploymentTargetMacroNames()
}
var hasLoadedExtendedInfo = false

Expand Down
5 changes: 4 additions & 1 deletion Sources/SWBCore/Settings/BuiltinMacros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1300,6 +1300,8 @@ public final class BuiltinMacros {
// Info.plist Keys - Sticker Packs
public static let INFOPLIST_KEY_NSStickerSharingLevel = BuiltinMacros.declareEnumMacro("INFOPLIST_KEY_NSStickerSharingLevel") as EnumMacroDeclaration<StickerSharingLevel>

public static let __SKIP_BUILD = BuiltinMacros.declareBooleanMacro("__SKIP_BUILD")

// MARK: Built-in Macro Initialization

private static var initialized = false
Expand Down Expand Up @@ -2391,7 +2393,8 @@ public final class BuiltinMacros {
ENABLE_XOJIT_PREVIEWS,
BUILD_ACTIVE_RESOURCES_ONLY,
ENABLE_ONLY_ACTIVE_RESOURCES,
ENABLE_PLAYGROUND_RESULTS
ENABLE_PLAYGROUND_RESULTS,
__SKIP_BUILD
]

/// Force initialization of entitlements macros.
Expand Down
8 changes: 4 additions & 4 deletions Sources/SWBCore/ShellScript.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public enum ScriptType: Sendable {
/// - settings: The settings to use for computing the script's environment and search paths.
/// - workspaceContext: The workspace context to use for computing the script's environment.
/// - scope: The scope in which to expand build settings.
public func constructCommandLine(for target: ExternalTarget, action: String, settings: Settings, workspaceContext: WorkspaceContext, scope: MacroEvaluationScope) -> (executable: String, arguments: [String], workingDirectory: Path, environment: [String: String]) {
public func constructCommandLine(for target: ExternalTarget, action: String, settings: Settings, workspaceContext: WorkspaceContext, scope: MacroEvaluationScope, allDeploymentTargetMacroNames: Set<String>) -> (executable: String, arguments: [String], workingDirectory: Path, environment: [String: String]) {
let scope = settings.globalScope
func lookup(_ macro: MacroDeclaration) -> MacroExpression? {
switch macro {
Expand All @@ -44,7 +44,7 @@ public func constructCommandLine(for target: ExternalTarget, action: String, set
let workingDirectory = (settings.project?.sourceRoot ?? workspaceContext.workspace.path.dirname).join(Path(scope.evaluate(target.workingDirectory, lookup: lookup)))
var environment: [String: String] = [:]
if target.passBuildSettingsInEnvironment {
environment = computeScriptEnvironment(.externalTarget, scope: scope, settings: settings, workspaceContext: workspaceContext)
environment = computeScriptEnvironment(.externalTarget, scope: scope, settings: settings, workspaceContext: workspaceContext, allDeploymentTargetMacroNames: allDeploymentTargetMacroNames)
}

// Always set ACTION in the environment.
Expand Down Expand Up @@ -77,7 +77,7 @@ public func constructCommandLine(for target: ExternalTarget, action: String, set
/// - scope: The scope in which to expand build settings.
/// - settings: The settings to use for computing the environment.
/// - workspaceContext: The workspace context to use for computing the environment
public func computeScriptEnvironment(_ type: ScriptType, scope: MacroEvaluationScope, settings: Settings, workspaceContext: WorkspaceContext) -> [String: String] {
public func computeScriptEnvironment(_ type: ScriptType, scope: MacroEvaluationScope, settings: Settings, workspaceContext: WorkspaceContext, allDeploymentTargetMacroNames: Set<String>) -> [String: String] {
var result = [String: String]()

// FIXME: Note that we merged this function for shell scripts with the very similar code that was used to build the environment for external build commands. Currently in order to retain perfect compatibility we do various things conditionally based on the mode, but really this code should just be a single function that is used for both contexts at some point.
Expand Down Expand Up @@ -202,7 +202,7 @@ public func computeScriptEnvironment(_ type: ScriptType, scope: MacroEvaluationS

// Remove deployment targets for platforms other than the one we're building for. <rdar://problem/20008508>
let ourDeploymentTargetName = scope.evaluate(BuiltinMacros.DEPLOYMENT_TARGET_SETTING_NAME)
for deploymentTargetNameToRemove in workspaceContext.core.platformRegistry.allDeploymentTargetMacroNames {
for deploymentTargetNameToRemove in allDeploymentTargetMacroNames {
if ourDeploymentTargetName.isEmpty || ourDeploymentTargetName != deploymentTargetNameToRemove {
result.removeValue(forKey: deploymentTargetNameToRemove)
}
Expand Down
Loading