@@ -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 }
0 commit comments