diff --git a/Sources/SWBAndroidPlatform/Plugin.swift b/Sources/SWBAndroidPlatform/Plugin.swift index 231bf41c..8ffd0044 100644 --- a/Sources/SWBAndroidPlatform/Plugin.swift +++ b/Sources/SWBAndroidPlatform/Plugin.swift @@ -65,10 +65,6 @@ struct AndroidEnvironmentExtension: EnvironmentExtension { } struct AndroidPlatformExtension: PlatformInfoExtension { - func knownDeploymentTargetMacroNames() -> Set { - ["ANDROID_DEPLOYMENT_TARGET"] - } - func additionalPlatforms(context: any PlatformInfoExtensionAdditionalPlatformsContext) throws -> [(path: Path, data: [String: PropertyListItem])] { [ (.root, [ diff --git a/Sources/SWBApplePlatform/Plugin.swift b/Sources/SWBApplePlatform/Plugin.swift index 50ae32d4..6be46f8e 100644 --- a/Sources/SWBApplePlatform/Plugin.swift +++ b/Sources/SWBApplePlatform/Plugin.swift @@ -207,17 +207,6 @@ struct XCStringsInputFileGroupingStrategyExtension: InputFileGroupingStrategyExt } struct ApplePlatformInfoExtension: PlatformInfoExtension { - func knownDeploymentTargetMacroNames() -> Set { - [ - "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 diff --git a/Sources/SWBBuildService/Messages.swift b/Sources/SWBBuildService/Messages.swift index 11159c04..2d5946c3 100644 --- a/Sources/SWBBuildService/Messages.swift +++ b/Sources/SWBBuildService/Messages.swift @@ -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) } diff --git a/Sources/SWBBuildSystem/CleanOperation.swift b/Sources/SWBBuildSystem/CleanOperation.swift index fce5fa8b..3c5c7054 100644 --- a/Sources/SWBBuildSystem/CleanOperation.swift +++ b/Sources/SWBBuildSystem/CleanOperation.swift @@ -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) diff --git a/Sources/SWBCore/Extensions/PlatformInfoExtension.swift b/Sources/SWBCore/Extensions/PlatformInfoExtension.swift index a0b8ac35..e1321c31 100644 --- a/Sources/SWBCore/Extensions/PlatformInfoExtension.swift +++ b/Sources/SWBCore/Extensions/PlatformInfoExtension.swift @@ -22,8 +22,6 @@ public struct PlatformInfoExtensionPoint: ExtensionPoint, Sendable { } public protocol PlatformInfoExtension: Sendable { - func knownDeploymentTargetMacroNames() -> Set - func preferredArchValue(for: String) -> String? func additionalTestLibraryPaths(scope: MacroEvaluationScope, platform: Platform?, fs: any FSProxy) -> [Path] @@ -40,10 +38,6 @@ public protocol PlatformInfoExtension: Sendable { } extension PlatformInfoExtension { - public func knownDeploymentTargetMacroNames() -> Set { - [] - } - public func preferredArchValue(for: String) -> String? { nil } diff --git a/Sources/SWBCore/PlatformRegistry.swift b/Sources/SWBCore/PlatformRegistry.swift index ec7b126b..bf4ec315 100644 --- a/Sources/SWBCore/PlatformRegistry.swift +++ b/Sources/SWBCore/PlatformRegistry.swift @@ -309,9 +309,6 @@ public final class PlatformRegistry { /// The map of platforms by name. var platformsByName = Dictionary() - /// 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() - /// The default deployment targets for all installed platforms. var defaultDeploymentTargets: [String: Version] { Dictionary(uniqueKeysWithValues: Dictionary(grouping: platforms, by: { $0.defaultSDKVariant?.deploymentTargetSettingName }) @@ -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]() - 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()].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: <) ?? [] { @@ -690,8 +647,6 @@ public final class PlatformRegistry { unregisterPlatform(platform) } } - - loadDeploymentTargetMacroNames() } var hasLoadedExtendedInfo = false diff --git a/Sources/SWBCore/ShellScript.swift b/Sources/SWBCore/ShellScript.swift index e6845d96..77191e9e 100644 --- a/Sources/SWBCore/ShellScript.swift +++ b/Sources/SWBCore/ShellScript.swift @@ -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) -> (executable: String, arguments: [String], workingDirectory: Path, environment: [String: String]) { let scope = settings.globalScope func lookup(_ macro: MacroDeclaration) -> MacroExpression? { switch macro { @@ -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. @@ -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] { 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. @@ -202,7 +202,7 @@ public func computeScriptEnvironment(_ type: ScriptType, scope: MacroEvaluationS // Remove deployment targets for platforms other than the one we're building for. 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) } diff --git a/Sources/SWBCore/SpecImplementations/CommandLineToolSpec.swift b/Sources/SWBCore/SpecImplementations/CommandLineToolSpec.swift index 5757442a..8c9fa145 100644 --- a/Sources/SWBCore/SpecImplementations/CommandLineToolSpec.swift +++ b/Sources/SWBCore/SpecImplementations/CommandLineToolSpec.swift @@ -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: /// /// { @@ -154,18 +154,17 @@ public final class DiscoveredCommandLineToolSpecInfoCache: Sendable { /// ] /// } /// -func rawFeaturesFromToolFeaturesJSON(path: Path, fs: any FSProxy) throws -> Set { - 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: Sendable where T: Sendable, T: Hashable, T: CaseIterable, T: RawRepresentable, T.RawValue == String { + private let featureSet: FeatureSet public let flags: Set public static var none: ToolFeatures { @@ -174,11 +173,13 @@ public struct ToolFeatures: Sendable where T: Sendable, T: Hashable, T: CaseI public init(_ flags: Set) { 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 = [] - 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) @@ -197,6 +198,10 @@ public struct ToolFeatures: 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 { diff --git a/Sources/SWBCore/ToolInfo/ClangToolInfo.swift b/Sources/SWBCore/ToolInfo/ClangToolInfo.swift index dcc80ccc..8fa43970 100644 --- a/Sources/SWBCore/ToolInfo/ClangToolInfo.swift +++ b/Sources/SWBCore/ToolInfo/ClangToolInfo.swift @@ -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 public func hasFeature(_ feature: String) -> Bool { @@ -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 { + Set(toolFeatures.value(.deploymentTargetEnvironmentVariables)?.stringArrayValue ?? []) + } } public struct ClangCachingBlockListInfo : ProjectFailuresBlockList, Codable, Sendable { diff --git a/Sources/SWBQNXPlatform/Plugin.swift b/Sources/SWBQNXPlatform/Plugin.swift index 89d1177c..487706c4 100644 --- a/Sources/SWBQNXPlatform/Plugin.swift +++ b/Sources/SWBQNXPlatform/Plugin.swift @@ -53,10 +53,6 @@ struct QNXEnvironmentExtension: EnvironmentExtension { } struct QNXPlatformExtension: PlatformInfoExtension { - func knownDeploymentTargetMacroNames() -> Set { - ["QNX_DEPLOYMENT_TARGET"] - } - func additionalPlatforms(context: any PlatformInfoExtensionAdditionalPlatformsContext) throws -> [(path: Path, data: [String: PropertyListItem])] { [ (.root, [ diff --git a/Sources/SWBTaskConstruction/TaskProducers/BuildPhaseTaskProducers/BuildRuleTaskProducer.swift b/Sources/SWBTaskConstruction/TaskProducers/BuildPhaseTaskProducers/BuildRuleTaskProducer.swift index 7874ced4..fd52d6ff 100644 --- a/Sources/SWBTaskConstruction/TaskProducers/BuildPhaseTaskProducers/BuildRuleTaskProducer.swift +++ b/Sources/SWBTaskConstruction/TaskProducers/BuildPhaseTaskProducers/BuildRuleTaskProducer.swift @@ -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 diff --git a/Sources/SWBTaskConstruction/TaskProducers/BuildPhaseTaskProducers/ShellScriptTaskProducer.swift b/Sources/SWBTaskConstruction/TaskProducers/BuildPhaseTaskProducers/ShellScriptTaskProducer.swift index c3a86d90..fedc42f6 100644 --- a/Sources/SWBTaskConstruction/TaskProducers/BuildPhaseTaskProducers/ShellScriptTaskProducer.swift +++ b/Sources/SWBTaskConstruction/TaskProducers/BuildPhaseTaskProducers/ShellScriptTaskProducer.swift @@ -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) @@ -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. diff --git a/Sources/SWBTaskConstruction/TaskProducers/OtherTaskProducers/CustomTaskProducer.swift b/Sources/SWBTaskConstruction/TaskProducers/OtherTaskProducers/CustomTaskProducer.swift index 57b15e66..5dc3f792 100644 --- a/Sources/SWBTaskConstruction/TaskProducers/OtherTaskProducers/CustomTaskProducer.swift +++ b/Sources/SWBTaskConstruction/TaskProducers/OtherTaskProducers/CustomTaskProducer.swift @@ -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" } } diff --git a/Sources/SWBTaskConstruction/TaskProducers/OtherTaskProducers/ExternalTargetTaskProducer.swift b/Sources/SWBTaskConstruction/TaskProducers/OtherTaskProducers/ExternalTargetTaskProducer.swift index be742c95..3e2a69d8 100644 --- a/Sources/SWBTaskConstruction/TaskProducers/OtherTaskProducers/ExternalTargetTaskProducer.swift +++ b/Sources/SWBTaskConstruction/TaskProducers/OtherTaskProducers/ExternalTargetTaskProducer.swift @@ -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 } diff --git a/Sources/SWBTaskConstruction/TaskProducers/TaskProducer.swift b/Sources/SWBTaskConstruction/TaskProducers/TaskProducer.swift index edfe281f..38501ae7 100644 --- a/Sources/SWBTaskConstruction/TaskProducers/TaskProducer.swift +++ b/Sources/SWBTaskConstruction/TaskProducers/TaskProducer.swift @@ -435,6 +435,11 @@ public class TaskProducerContext: StaleFileRemovalContext, BuildFileResolution } } + /// The set of all known deployment target macro names, even if the platforms that use those settings are not installed. + func allDeploymentTargetMacroNames() async -> Set { + await (clangSpec.discoveredCommandLineToolSpecInfo(self, settings.globalScope, delegate) as? DiscoveredClangToolSpecInfo)?.deploymentTargetEnvironmentVariableNames() ?? [] + } + /// Make an input path absolute, resolving relative to the current project. func makeAbsolute(_ path: Path) -> Path { return defaultWorkingDirectory.join(path) diff --git a/Tests/SWBCoreTests/ShellScriptEnvironmentTests.swift b/Tests/SWBCoreTests/ShellScriptEnvironmentTests.swift index 16100daf..ce638d1f 100644 --- a/Tests/SWBCoreTests/ShellScriptEnvironmentTests.swift +++ b/Tests/SWBCoreTests/ShellScriptEnvironmentTests.swift @@ -49,7 +49,7 @@ import SWBProtocol let parameters = BuildParameters(action: .build, configuration: "Debug", overrides: [:]) let settings = Settings(workspaceContext: context, buildRequestContext: buildRequestContext, parameters: parameters, project: testProject, target: testTarget) - let env = SWBCore.computeScriptEnvironment(.shellScriptPhase, scope: settings.globalScope, settings: settings, workspaceContext: context) + let env = SWBCore.computeScriptEnvironment(.shellScriptPhase, scope: settings.globalScope, settings: settings, workspaceContext: context, allDeploymentTargetMacroNames: []) let expected: [String: String] = [ "ACTION": "build", @@ -209,7 +209,7 @@ import SWBProtocol let parameters = BuildParameters(action: .build, configuration: "Debug", overrides: [:], toolchainOverride: "com.apple.ExtraToolchain") let settings = Settings(workspaceContext: context, buildRequestContext: buildRequestContext, parameters: parameters, project: testProject, target: testTarget) - let env = SWBCore.computeScriptEnvironment(.shellScriptPhase, scope: settings.globalScope, settings: settings, workspaceContext: context) + let env = SWBCore.computeScriptEnvironment(.shellScriptPhase, scope: settings.globalScope, settings: settings, workspaceContext: context, allDeploymentTargetMacroNames: []) // Check that all of the settings defined as expected in the dictionary above appear as described. let expected: [String: String] = [ @@ -257,7 +257,7 @@ import SWBProtocol let parameters = BuildParameters(action: .build, configuration: "Debug", overrides: [:]) let settings = Settings(workspaceContext: context, buildRequestContext: buildRequestContext, parameters: parameters, project: testProject, target: testTarget) - let env = SWBCore.computeScriptEnvironment(.shellScriptPhase, scope: settings.globalScope, settings: settings, workspaceContext: context) + let env = SWBCore.computeScriptEnvironment(.shellScriptPhase, scope: settings.globalScope, settings: settings, workspaceContext: context, allDeploymentTargetMacroNames: []) let shouldNotBeExported = [ "BUILD_DESCRIPTION_CACHE_DIR", diff --git a/Tests/SWBTaskConstructionTests/ShellScriptTaskConstructionTests.swift b/Tests/SWBTaskConstructionTests/ShellScriptTaskConstructionTests.swift index ed758671..c04bbef6 100644 --- a/Tests/SWBTaskConstructionTests/ShellScriptTaskConstructionTests.swift +++ b/Tests/SWBTaskConstructionTests/ShellScriptTaskConstructionTests.swift @@ -109,7 +109,7 @@ fileprivate struct ShellScriptTaskConstructionTests: CoreBasedTests { extension CoreBasedTests { func testShellScriptDeploymentTargetPruning(sdkroot: String, sdkVariant: String? = nil, expectedDeploymentTargetPrefix: String) async throws { - let testProject = TestProject( + let testProject = try await TestProject( "MyProject", sourceRoot: Path("/MyProject"), groupTree: TestGroup("Group"), @@ -117,6 +117,7 @@ extension CoreBasedTests { TestBuildConfiguration( "Debug", buildSettings: [ + "CC": clangCompilerPath.str, "CODE_SIGNING_ALLOWED": "NO", "PRODUCT_NAME": "$(TARGET_NAME)", "SDKROOT": sdkroot, @@ -147,7 +148,14 @@ extension CoreBasedTests { results.checkTask(.matchRuleType("PhaseScriptExecution")) { task in let env = task.environment.bindingsDictionary - let otherNames = Set(["SWIFT_DEPLOYMENT_TARGET", "RESOURCES_MINIMUM_DEPLOYMENT_TARGET"]) + let otherNames = Set([ + "SWIFT_DEPLOYMENT_TARGET", + "RESOURCES_MINIMUM_DEPLOYMENT_TARGET", + + // Not actually recognized by clang + "ANDROID_DEPLOYMENT_TARGET", + "QNX_DEPLOYMENT_TARGET", + ]) let suffix = "_DEPLOYMENT_TARGET" let deploymentTargetSettingNames = env.compactMap { key, _ in !otherNames.contains(key) && !key.hasPrefix("SWIFT_MODULE_ONLY_") && !key.hasPrefix("RECOMMENDED_") && key.hasSuffix(suffix) ? key : nil } #expect(deploymentTargetSettingNames == [expectedDeploymentTargetPrefix + suffix])