Skip to content

Commit 94ed881

Browse files
Merge pull request #700 from swiftlang/automerge/merge-main-2025-08-02_00-48
Merge `release/6.2` into `main`
2 parents 12952a3 + 8f7a93f commit 94ed881

22 files changed

+188
-48
lines changed

Sources/SWBApplePlatform/AssetCatalogCompiler.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,12 @@ public final class ActoolCompilerSpec : GenericCompilerSpec, SpecIdentifierType,
239239
// which it currently receives a listing of via the assetcatalog_dependencies file produced by actool.
240240
let carFiles = [cbc.resourcesDir?.join("Assets.car")].compactMap { $0 }.map(delegate.createNode)
241241

242-
let outputs = evaluatedOutputsResult + (additionalEvaluatedOutputsResult.outputs ).map(delegate.createNode)
242+
let outputs = evaluatedOutputsResult + (additionalEvaluatedOutputsResult.outputs).map { output in
243+
if let fileTypeIdentifier = output.fileType, let fileType = cbc.producer.lookupFileType(identifier: fileTypeIdentifier) {
244+
delegate.declareOutput(FileToBuild(absolutePath: output.path, fileType: fileType))
245+
}
246+
return delegate.createNode(output.path)
247+
}
243248
guard !outputs.isEmpty else { preconditionFailure("ActoolCompilerSpec.constructTasks() invoked with no outputs defined") }
244249

245250
let assetSymbolInputs = cbc.inputs

Sources/SWBApplePlatform/InterfaceBuilderCompiler.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,12 @@ public class IbtoolCompilerSpec : GenericCompilerSpec, IbtoolCompilerSupport, @u
8686

8787
// Add the additional outputs defined by the spec. These are not declared as outputs but should be processed by the tool separately.
8888
let additionalEvaluatedOutputsResult = await additionalEvaluatedOutputs(cbc, delegate)
89-
outputs += additionalEvaluatedOutputsResult.outputs.map(delegate.createNode)
89+
outputs += additionalEvaluatedOutputsResult.outputs.map { output in
90+
if let fileTypeIdentifier = output.fileType, let fileType = cbc.producer.lookupFileType(identifier: fileTypeIdentifier) {
91+
delegate.declareOutput(FileToBuild(absolutePath: output.path, fileType: fileType))
92+
}
93+
return delegate.createNode(output.path)
94+
}
9095

9196
if let infoPlistContent = additionalEvaluatedOutputsResult.generatedInfoPlistContent {
9297
delegate.declareGeneratedInfoPlistContent(infoPlistContent)

Sources/SWBApplePlatform/Plugin.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ struct AppleDeveloperDirectoryExtension: DeveloperDirectoryExtension {
3737
}
3838

3939
struct TaskProducersExtension: TaskProducerExtension {
40-
4140
func createPreSetupTaskProducers(_ context: TaskProducerContext) -> [any TaskProducer] {
4241
[DevelopmentAssetsTaskProducer(context)]
4342
}
@@ -61,6 +60,9 @@ struct TaskProducersExtension: TaskProducerExtension {
6160
var globalTaskProducers: [any GlobalTaskProducerFactory] {
6261
[StubBinaryTaskProducerFactory()]
6362
}
63+
64+
func generateAdditionalTasks(_ tasks: inout [any SWBCore.PlannedTask], _ producer: any SWBTaskConstruction.TaskProducer) {
65+
}
6466
}
6567

6668
struct ExtensionPointExtractorTaskProducerFactory: TaskProducerFactory {

Sources/SWBCore/Core.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,7 @@ public final class Core: Sendable {
596596

597597
let specs: [SpecDump] = specRegistry.domains.flatMap { domain -> [SpecDump] in
598598
let allSpecs = specRegistry.findSpecs(BuildSettingsSpec.self, domain: domain, includeInherited: false)
599+
+ specRegistry.findSpecs(BuildSettingsExtensionSpec.self, domain: domain, includeInherited: false)
599600
+ specRegistry.findSpecs(BuildSystemSpec.self, domain: domain, includeInherited: false)
600601
+ specRegistry.findSpecs(CommandLineToolSpec.self, domain: domain, includeInherited: false)
601602
return allSpecs.map { spec in

Sources/SWBCore/Settings/Settings.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ fileprivate struct PreOverridesSettings {
8383
let ignoredMacros: [MacroDeclaration] = [BuiltinMacros.OutputFormat, BuiltinMacros.OutputPath]
8484

8585
for spec in specs {
86-
for option in spec.flattenedBuildOptions.values {
86+
for option in core.specRegistry.effectiveFlattenedBuildOptions(spec).values {
8787
guard !ignoredMacros.contains(option.macro) else { continue }
8888

8989
if let value = option.defaultValue {
@@ -236,11 +236,11 @@ fileprivate struct PreOverridesSettings {
236236
// Add the defaults from all the registered tools in the given domain.
237237
//
238238
// FIXME: This is somewhat wasteful, as we end up duplicating values for super specifications. However, that lets us keep the condition set required to enable a particular compiler very simple.
239-
let unionedDefaults = unionedToolDefaults(domain: domain)
239+
let unionedDefaults = unionedToolDefaults(domain: domain).table
240240
let customizedDefaults = MacroValueAssignmentTable(namespace: core.specRegistry.internalMacroNamespace)
241241
for spec in core.specRegistry.findSpecs(CompilerSpec.self, domain: domain) {
242242
// Add all the necessary defaults.
243-
for option in spec.flattenedBuildOptions.values {
243+
for option in core.specRegistry.effectiveFlattenedBuildOptions(spec).values {
244244
if let defaultValue = option.defaultValue {
245245
// Only push the default value if it diverges from the existing default.
246246
//

Sources/SWBCore/SpecImplementations/CommandLineToolSpec.swift

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti
776776
let scope = cbc.scope
777777
let inputFileType = cbc.inputs.first?.fileType
778778
let lookup = { self.lookup($0, cbc, delegate) }
779-
for buildOption in self.flattenedOrderedBuildOptions {
779+
for buildOption in cbc.producer.effectiveFlattenedOrderedBuildOptions(self) {
780780
guard let dependencyFormat = buildOption.dependencyFormat else {
781781
continue
782782
}
@@ -916,7 +916,12 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti
916916

917917
// Add the additional outputs defined by the spec. These are not declared as outputs but should be processed by the tool separately.
918918
let additionalEvaluatedOutputsResult = await additionalEvaluatedOutputs(cbc, delegate)
919-
outputs.append(contentsOf: additionalEvaluatedOutputsResult.outputs.map({ delegate.createNode($0) }))
919+
outputs.append(contentsOf: additionalEvaluatedOutputsResult.outputs.map { output in
920+
if let fileTypeIdentifier = output.fileType, let fileType = cbc.producer.lookupFileType(identifier: fileTypeIdentifier) {
921+
delegate.declareOutput(FileToBuild(absolutePath: output.path, fileType: fileType))
922+
}
923+
return delegate.createNode(output.path)
924+
})
920925

921926
if let infoPlistContent = additionalEvaluatedOutputsResult.generatedInfoPlistContent {
922927
delegate.declareGeneratedInfoPlistContent(infoPlistContent)
@@ -978,7 +983,7 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti
978983
}
979984

980985
public struct AdditionalEvaluatedOutputsResult {
981-
public var outputs = [Path]()
986+
public var outputs = [(path: Path, fileType: String?)]()
982987
public var generatedInfoPlistContent: Path? = nil
983988
}
984989

@@ -994,20 +999,25 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti
994999

9951000
// FIXME: In Xcode, this is also marked as an "auxiliary output", which we use in conjunction with the "MightNotEmitAllOutput" flag to determine whether or not the tool needs to rerun if the output is missing.
9961001

997-
result.outputs.append(output)
1002+
result.outputs.append((output, nil))
9981003
}
9991004

10001005
let producer = cbc.producer
10011006
let scope = cbc.scope
10021007
let inputFileType = cbc.inputs.first?.fileType
10031008
let lookup = { self.lookup($0, cbc, delegate) }
10041009
let optionContext = await discoveredCommandLineToolSpecInfo(producer, scope, delegate)
1005-
result.outputs.append(contentsOf: self.flattenedOrderedBuildOptions.flatMap { buildOption -> [Path] in
1010+
result.outputs.append(contentsOf: cbc.producer.effectiveFlattenedOrderedBuildOptions(self, filter: .all).flatMap { buildOption -> [(Path, String?)] in
10061011
// Check if the effective arguments for this build option were non-empty as a proxy for whether it got filtered out by architecture mismatch, etc.
10071012
guard let outputDependencies = buildOption.outputDependencies, !buildOption.getArgumentsForCommand(producer, scope: scope, inputFileType: inputFileType, optionContext: optionContext, lookup: lookup).isEmpty else {
10081013
return []
10091014
}
1010-
return outputDependencies.compactMap { Path(scope.evaluate($0, lookup: lookup)).nilIfEmpty?.normalize() }
1015+
return outputDependencies.compactMap { outputDependency in
1016+
guard let path = Path(scope.evaluate(outputDependency.path, lookup: lookup)).nilIfEmpty else {
1017+
return nil
1018+
}
1019+
return (path.normalize(), outputDependency.fileType.map { scope.evaluate($0, lookup: lookup).nilIfEmpty } ?? nil)
1020+
}
10111021
})
10121022

10131023
return result
@@ -1231,7 +1241,7 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti
12311241
return cbc.scope.evaluate(value, lookup: lookup).map { .literal(ByteString(encodingAsUTF8: $0)) }
12321242

12331243
case .options:
1234-
return self.commandLineFromOptions(cbc, delegate, optionContext: optionContext, lookup: lookup)
1244+
return self.commandLineFromOptions(cbc, delegate, optionContext: optionContext, buildOptionsFilter: .all, lookup: lookup)
12351245

12361246
case .output:
12371247
// We always resolve the Output via a recursive macro evaluation. See constructTasks() for more information.
@@ -1260,22 +1270,22 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti
12601270
/// Creates and returns the command line arguments generated by the options of the specification.
12611271
///
12621272
/// - parameter lookup: An optional closure which functionally defined overriding values during build setting evaluation.
1263-
public func commandLineFromOptions(_ producer: any CommandProducer, scope: MacroEvaluationScope, inputFileType: FileTypeSpec?, optionContext: (any BuildOptionGenerationContext)?, lookup: ((MacroDeclaration) -> MacroExpression?)? = nil) -> [CommandLineArgument] {
1264-
return self.flattenedOrderedBuildOptions.flatMap { $0.getArgumentsForCommand(producer, scope: scope, inputFileType: inputFileType, optionContext: optionContext, lookup: lookup) }
1273+
public func commandLineFromOptions(_ producer: any CommandProducer, scope: MacroEvaluationScope, inputFileType: FileTypeSpec?, optionContext: (any BuildOptionGenerationContext)?, buildOptionsFilter: BuildOptionsFilter, lookup: ((MacroDeclaration) -> MacroExpression?)? = nil) -> [CommandLineArgument] {
1274+
return producer.effectiveFlattenedOrderedBuildOptions(self, filter: buildOptionsFilter).flatMap { $0.getArgumentsForCommand(producer, scope: scope, inputFileType: inputFileType, optionContext: optionContext, lookup: lookup) }
12651275
}
12661276

12671277
/// Creates and returns the command line arguments generated by the options of the specification.
12681278
///
12691279
/// - parameter lookup: An optional closure which functionally defined overriding values during build setting evaluation.
1270-
public func commandLineFromOptions(_ cbc: CommandBuildContext, _ delegate: any DiagnosticProducingDelegate, optionContext: (any BuildOptionGenerationContext)?, lookup: ((MacroDeclaration) -> MacroExpression?)? = nil) -> [CommandLineArgument] {
1271-
return commandLineFromOptions(cbc.producer, scope: cbc.scope, inputFileType: cbc.inputs.first?.fileType, optionContext: optionContext, lookup: { self.lookup($0, cbc, delegate, lookup) })
1280+
public func commandLineFromOptions(_ cbc: CommandBuildContext, _ delegate: any DiagnosticProducingDelegate, optionContext: (any BuildOptionGenerationContext)?, buildOptionsFilter: BuildOptionsFilter = .all, lookup: ((MacroDeclaration) -> MacroExpression?)? = nil) -> [CommandLineArgument] {
1281+
return commandLineFromOptions(cbc.producer, scope: cbc.scope, inputFileType: cbc.inputs.first?.fileType, optionContext: optionContext, buildOptionsFilter: buildOptionsFilter, lookup: { self.lookup($0, cbc, delegate, lookup) })
12721282
}
12731283

12741284
/// Creates and returns the command line arguments generated by the specification's build setting corresponding to the given macro declaration.
12751285
///
12761286
/// - parameter lookup: An optional closure which functionally defined overriding values during build setting evaluation.
12771287
func commandLineFromMacroDeclaration(_ producer: any CommandProducer, optionContext: (any BuildOptionGenerationContext)?, scope: MacroEvaluationScope, macro: MacroDeclaration, inputFileType: FileTypeSpec?, lookup: ((MacroDeclaration) -> MacroExpression?)? = nil) -> [CommandLineArgument] {
1278-
return buildOptions.first { $0.name == macro.name }?.getArgumentsForCommand(producer, scope: scope, inputFileType: inputFileType, optionContext: optionContext, lookup: lookup) ?? []
1288+
return producer.effectiveBuildOptions(self).first { $0.name == macro.name }?.getArgumentsForCommand(producer, scope: scope, inputFileType: inputFileType, optionContext: optionContext, lookup: lookup) ?? []
12791289
}
12801290

12811291
/// Creates and returns the command line arguments generated by the specification's build setting corresponding to the given macro declaration.
@@ -1291,7 +1301,7 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti
12911301
let scope = cbc.scope
12921302
let inputFileType = cbc.inputs.first?.fileType
12931303
let lookup = { self.lookup($0, cbc, delegate, lookup) }
1294-
return self.flattenedOrderedBuildOptions.flatMap { buildOption -> [Path] in
1304+
return cbc.producer.effectiveFlattenedOrderedBuildOptions(self).flatMap { buildOption -> [Path] in
12951305
// Check if the effective arguments for this build option were non-empty as a proxy for whether it got filtered out by architecture mismatch, etc.
12961306
guard let inputInclusions = buildOption.inputInclusions, !buildOption.getArgumentsForCommand(producer, scope: scope, inputFileType: inputFileType, optionContext: optionContext, lookup: lookup).isEmpty else {
12971307
return []
@@ -1303,7 +1313,7 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti
13031313
/// Compute the list of additional linker arguments to use when this tool is used for building with the given scope.
13041314
public func computeAdditionalLinkerArgs(_ producer: any CommandProducer, scope: MacroEvaluationScope, inputFileTypes: [FileTypeSpec], optionContext: (any BuildOptionGenerationContext)?, delegate: any TaskGenerationDelegate) async -> (args: [[String]], inputPaths: [Path]) {
13051315
// FIXME: Optimize the list to search here.
1306-
return (args: self.flattenedOrderedBuildOptions.map { $0.getAdditionalLinkerArgs(producer, scope: scope, inputFileTypes: inputFileTypes) }, inputPaths: [])
1316+
return (args: producer.effectiveFlattenedOrderedBuildOptions(self).map { $0.getAdditionalLinkerArgs(producer, scope: scope, inputFileTypes: inputFileTypes) }, inputPaths: [])
13071317
}
13081318

13091319
// Creates and returns the environment from the specification. This includes both the 'EnvironmentVariables' property for this tool spec, and any build options which define that their value should be exported via their 'SetValueInEnvironmentVariable' property.
@@ -1319,7 +1329,7 @@ open class CommandLineToolSpec : PropertyDomainSpec, SpecType, TaskTypeDescripti
13191329

13201330
// Add environment variables from build options which specify they should be added via a 'SetValueInEnvironmentVariable' property.
13211331
// FIXME: Optimize the list to search here.
1322-
for buildOption in self.flattenedOrderedBuildOptions {
1332+
for buildOption in cbc.producer.effectiveFlattenedOrderedBuildOptions(self) {
13231333
if let assignment = buildOption.getEnvironmentAssignmentForCommand(cbc, lookup: wrappedLookup) {
13241334
environment.append(assignment)
13251335
}

Sources/SWBCore/SpecImplementations/PropertyDomainSpec.swift

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ private let buildOptionTypes: [String: any BuildOptionType] = [
345345
let inputInclusions: [MacroStringExpression]?
346346

347347
/// Additional output dependencies to consider when this build option is active.
348-
let outputDependencies: [MacroStringExpression]?
348+
let outputDependencies: [(path: MacroStringExpression, fileType: MacroStringExpression?)]?
349349

350350
/// Helper function for extract an individual value definition from a dictionary.
351351
private static func parseBuildOptionValue(_ parser: SpecParser, _ name: String, _ type: any BuildOptionType, _ data: [String: PropertyListItem]) -> (String, BuildOptionValue)? {
@@ -806,7 +806,7 @@ private let buildOptionTypes: [String: any BuildOptionType] = [
806806
var dependencyFormat: DependencyDataFormat? = nil
807807
var featureFlags: [String]? = nil
808808
var inputInclusions: [MacroStringExpression]? = nil
809-
var outputDependencies: [MacroStringExpression]? = nil
809+
var outputDependencies: [(path: MacroStringExpression, fileType: MacroStringExpression?)]? = nil
810810
for (key, valueData) in items {
811811
switch key {
812812
case "Name":
@@ -1033,14 +1033,36 @@ private let buildOptionTypes: [String: any BuildOptionType] = [
10331033
case "OutputDependencies":
10341034
switch valueData {
10351035
case .plString(let value):
1036-
outputDependencies = [parser.delegate.internalMacroNamespace.parseString(value)]
1036+
outputDependencies = [(parser.delegate.internalMacroNamespace.parseString(value), nil)]
10371037
case .plArray(let values):
10381038
outputDependencies = values.compactMap({ data in
1039-
guard case .plString(let value) = data else {
1040-
error("expected all string values in array for '\(key)'")
1039+
switch data {
1040+
case let .plString(value):
1041+
return (parser.delegate.internalMacroNamespace.parseString(value), nil)
1042+
case let .plDict(value):
1043+
let path: MacroStringExpression
1044+
switch value["Path"] {
1045+
case let .plString(expr):
1046+
path = parser.delegate.internalMacroNamespace.parseString(expr)
1047+
default:
1048+
error("expected string value for subkey 'Path' in element of array in '\(key)'")
1049+
return nil
1050+
}
1051+
1052+
let fileType: MacroStringExpression
1053+
switch value["FileType"] {
1054+
case let .plString(expr):
1055+
fileType = parser.delegate.internalMacroNamespace.parseString(expr)
1056+
default:
1057+
error("expected string value for subkey 'FileType' in element of array in '\(key)'")
1058+
return nil
1059+
}
1060+
1061+
return (path, fileType)
1062+
default:
1063+
error("expected all string or dictionary values in array for '\(key)'")
10411064
return nil
10421065
}
1043-
return parser.delegate.internalMacroNamespace.parseString(value)
10441066
})
10451067
default:
10461068
error("expected string or array value for build option key '\(key)'")
@@ -1722,11 +1744,11 @@ open class PropertyDomainSpec : Spec, @unchecked Sendable {
17221744

17231745

17241746
/// Extensions to PropertyDomainSpec for performance testing.
1725-
public extension PropertyDomainSpec {
1747+
extension PropertyDomainSpec {
17261748

17271749
/// Creates and returns a ``MacroValueAssignmentTable`` populated with the default values of the receiver's build options.
17281750
/// The table's namespace is also returned so that the caller can add further settings to it if desired.
1729-
func macroTableForBuildOptionDefaults(_ core: Core) -> (MacroValueAssignmentTable, MacroNamespace) {
1751+
@_spi(Testing) public func macroTableForBuildOptionDefaults(_ core: Core) -> (MacroValueAssignmentTable, MacroNamespace) {
17301752
var table = MacroValueAssignmentTable(namespace: core.specRegistry.internalMacroNamespace)
17311753
for option in self.flattenedOrderedBuildOptions {
17321754
guard let value = option.defaultValue else { continue }

0 commit comments

Comments
 (0)