Skip to content
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
4 changes: 0 additions & 4 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
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
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
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
23 changes: 14 additions & 9 deletions Sources/SWBCore/SpecImplementations/CommandLineToolSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public final class DiscoveredCommandLineToolSpecInfoCache: Sendable {
}
}

/// Returns the set of 'feature' names detailed in a 'features.json' file that a tool may install alongside its executable.
/// Represents the set of 'feature' names detailed in a 'features.json' file that a tool may install alongside its executable.
/// The format is like this:
///
/// {
Expand All @@ -154,18 +154,17 @@ public final class DiscoveredCommandLineToolSpecInfoCache: Sendable {
/// ]
/// }
///
func rawFeaturesFromToolFeaturesJSON(path: Path, fs: any FSProxy) throws -> Set<String> {
struct FeatureSet: Codable {
struct Feature: Codable {
let name: String
}
let features: [Feature]
private struct FeatureSet: Codable {
struct Feature: Codable {
let name: String
let value: PropertyListItem?
}
return try Set(JSONDecoder().decode(FeatureSet.self, from: path, fs: fs).features.map(\.name))
let features: [Feature]
}

/// Set of features from a 'features.json' file that may be installed alongside its executable, see `rawFeaturesFromToolFeaturesJSON`.
public struct ToolFeatures<T>: Sendable where T: Sendable, T: Hashable, T: CaseIterable, T: RawRepresentable, T.RawValue == String {
private let featureSet: FeatureSet
public let flags: Set<T>

public static var none: ToolFeatures {
Expand All @@ -174,11 +173,13 @@ public struct ToolFeatures<T>: Sendable where T: Sendable, T: Hashable, T: CaseI

public init(_ flags: Set<T>) {
self.flags = flags
self.featureSet = .init(features: flags.map { .init(name: $0.rawValue, value: nil) })
}

public init(path: Path, fs: any FSProxy) throws {
var flags: Set<T> = []
let raw = try rawFeaturesFromToolFeaturesJSON(path: path, fs: fs)
featureSet = try JSONDecoder().decode(FeatureSet.self, from: path, fs: fs)
let raw = Set(featureSet.features.map(\.name))
for flag in T.allCases {
if raw.contains(flag.rawValue) {
flags.insert(flag)
Expand All @@ -197,6 +198,10 @@ public struct ToolFeatures<T>: Sendable where T: Sendable, T: Hashable, T: CaseI
}
return has(flag)
}

public func value(_ flag: T) -> PropertyListItem? {
featureSet.features.first(where: { $0.name == flag.rawValue })?.value
}
}

public struct ProjectVersionInfo {
Expand Down
5 changes: 5 additions & 0 deletions Sources/SWBCore/ToolInfo/ClangToolInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public struct DiscoveredClangToolSpecInfo: DiscoveredCommandLineToolSpecInfo {
case resourceDirUsesMajorVersionOnly = "resource-dir-uses-major-version-only"
case wSystemHeadersInModule = "Wsystem-headers-in-module"
case extractAPISupportsCPlusPlus = "extract-api-supports-cpp"
case deploymentTargetEnvironmentVariables = "deployment-target-environment-variables"
}
public var toolFeatures: ToolFeatures<FeatureFlag>
public func hasFeature(_ feature: String) -> Bool {
Expand All @@ -56,6 +57,10 @@ public struct DiscoveredClangToolSpecInfo: DiscoveredCommandLineToolSpecInfo {
let version = hasFeature(FeatureFlag.resourceDirUsesMajorVersionOnly.rawValue) ? llvmVersion?[0].description : llvmVersion?.description
return version == nil ? nil : toolPath.dirname.dirname.join("lib").join("clang").join(version)
}

public func deploymentTargetEnvironmentVariableNames() -> Set<String> {
Set(toolFeatures.value(.deploymentTargetEnvironmentVariables)?.stringArrayValue ?? [])
}
}

public struct ClangCachingBlockListInfo : ProjectFailuresBlockList, Codable, Sendable {
Expand Down
4 changes: 0 additions & 4 deletions Sources/SWBQNXPlatform/Plugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ struct QNXEnvironmentExtension: EnvironmentExtension {
}

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

func additionalPlatforms(context: any PlatformInfoExtensionAdditionalPlatformsContext) throws -> [(path: Path, data: [String: PropertyListItem])] {
[
(.root, [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ final class BuildRuleTaskProducer: StandardTaskProducer, TaskProducer, ShellBase
let commandLine = [action.interpreterPath, "-c", action.scriptSource]

// Compute the environment to use for the shell script.
var environment = computeScriptEnvironment(.shellScriptPhase, scope: cbc.scope, settings: context.settings, workspaceContext: context.workspaceContext)
var environment = await computeScriptEnvironment(.shellScriptPhase, scope: cbc.scope, settings: context.settings, workspaceContext: context.workspaceContext, allDeploymentTargetMacroNames: context.allDeploymentTargetMacroNames())

// If we are in a headers build phase, expose visibility and output dir
// information to the script and set the HEADER_OUTPUT_DIR macro value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ final class ShellScriptTaskProducer: PhasedTaskProducer, TaskProducer, ShellBase
}

// Compute the environment to use for the shell script.
var environment = computeScriptEnvironment(.shellScriptPhase, scope: scope, settings: context.settings, workspaceContext: context.workspaceContext)
var environment = await computeScriptEnvironment(.shellScriptPhase, scope: scope, settings: context.settings, workspaceContext: context.workspaceContext, allDeploymentTargetMacroNames: context.allDeploymentTargetMacroNames())

// Create the set of resolved paths and export the proper variables to the script environment.
var inputs = exportPaths(&environment, shellScriptBuildPhase.inputFilePaths, prefix: "SCRIPT_INPUT_FILE", considerAllPathsDirectories: true)
Expand Down Expand Up @@ -308,10 +308,10 @@ final class ShellScriptTaskProducer: PhasedTaskProducer, TaskProducer, ShellBase
/// Construct the tasks for an individual shell-script build rule.
///
/// NOTE: External targets are basically shell scripts. It lives here because the behavior shares some significant logical pieces with the behavior of shell script build phases.
static func constructTasksForExternalTarget(_ target: SWBCore.ExternalTarget, _ context: TaskProducerContext, cbc: CommandBuildContext, delegate: any TaskGenerationDelegate) {
static func constructTasksForExternalTarget(_ target: SWBCore.ExternalTarget, _ context: TaskProducerContext, cbc: CommandBuildContext, delegate: any TaskGenerationDelegate) async {
let action = cbc.scope.evaluate(BuiltinMacros.ACTION)

let (executable, arguments, workingDirectory, environment) = constructCommandLine(for: target, action: action, settings: context.settings, workspaceContext: context.workspaceContext, scope: cbc.scope)
let (executable, arguments, workingDirectory, environment) = await constructCommandLine(for: target, action: action, settings: context.settings, workspaceContext: context.workspaceContext, scope: cbc.scope, allDeploymentTargetMacroNames: context.allDeploymentTargetMacroNames())

// FIXME: Need the model name.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ final class CustomTaskProducer: PhasedTaskProducer, TaskProducer {
for customTask in context.configuredTarget?.target.customTasks ?? [] {

let commandLine = customTask.commandLine.map { context.settings.globalScope.evaluate($0) }
var environmentAssignments = computeScriptEnvironment(.shellScriptPhase, scope: context.settings.globalScope, settings: context.settings, workspaceContext: context.workspaceContext)
var environmentAssignments = await computeScriptEnvironment(.shellScriptPhase, scope: context.settings.globalScope, settings: context.settings, workspaceContext: context.workspaceContext, allDeploymentTargetMacroNames: context.allDeploymentTargetMacroNames())
if context.workspaceContext.core.hostOperatingSystem != .macOS {
environmentAssignments = environmentAssignments.filter { $0.key.lowercased() != "path" }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ final class ExternalTargetTaskProducer: StandardTaskProducer, TaskProducer {
let target = context.configuredTarget!.target as! ExternalTarget
var tasks = [any PlannedTask]()
await appendGeneratedTasks(&tasks) { delegate in
ShellScriptTaskProducer.constructTasksForExternalTarget(target, context, cbc: CommandBuildContext(producer: context, scope: context.settings.globalScope, inputs: []), delegate: delegate)
await ShellScriptTaskProducer.constructTasksForExternalTarget(target, context, cbc: CommandBuildContext(producer: context, scope: context.settings.globalScope, inputs: []), delegate: delegate)
}
return tasks
}
Expand Down
Loading
Loading