@@ -102,14 +102,23 @@ func (p *sourcePreparerImpl) PrepareSources(
102102
103103 if applyOverlays {
104104 // Emit computed macros to a macros file in the output directory.
105+ // If the build configuration produces no macros, no file is written and
106+ // macrosFileName will be empty, signaling postProcessSources to skip
107+ // injecting the macro load directive and Source9999 tag.
108+ var macrosFileName string
109+
105110 macrosFilePath , err := p .writeMacrosFile (component , outputDir )
106111 if err != nil {
107112 return fmt .Errorf ("failed to write macros file for component %#q:\n %w" ,
108113 component .GetName (), err )
109114 }
110115
116+ if macrosFilePath != "" {
117+ macrosFileName = filepath .Base (macrosFilePath )
118+ }
119+
111120 // Apply any postprocessing to the sources in-place, in the output directory.
112- err = p .postProcessSources (component , outputDir , filepath . Base ( macrosFilePath ) )
121+ err = p .postProcessSources (component , outputDir , macrosFileName )
113122 if err != nil {
114123 return fmt .Errorf ("failed to post-process sources for component %q:\n %w" , component .GetName (), err )
115124 }
@@ -120,10 +129,13 @@ func (p *sourcePreparerImpl) PrepareSources(
120129
121130// writeMacrosFile writes a macros file containing the resolved macros for a component.
122131// This includes with/without flags converted to macro format, and any explicit defines.
123- // The file is always created, even if empty (aside from the header comment). Returns
124- // the path to the written macros file, which is guaranteed to be within the given outputDir .
132+ // If the build configuration produces no macros, no file is written and an empty path is
133+ // returned. Otherwise, the path to the written macros file is returned .
125134func (p * sourcePreparerImpl ) writeMacrosFile (component components.Component , outputDir string ) (string , error ) {
126135 contents := GenerateMacrosFileContents (component .GetConfig ().Build )
136+ if contents == "" {
137+ return "" , nil
138+ }
127139
128140 macrosFilePath := filepath .Join (outputDir , component .GetName ()+ MacrosFileExtension )
129141
@@ -156,11 +168,10 @@ func (p *sourcePreparerImpl) writeMacrosFile(component components.Component, out
156168//
157169// Note: RPM macro values can contain spaces without special escaping; everything
158170// after the macro name (and separating whitespace) is treated as the macro body.
171+ //
172+ // If no macros remain after processing (empty config, or all macros removed via
173+ // undefines), an empty string is returned to signal that no macros file is needed.
159174func GenerateMacrosFileContents (buildConfig projectconfig.ComponentBuildConfig ) string {
160- lines := []string {
161- MacrosFileHeader ,
162- }
163-
164175 // Build a unified map of all macros. Later definitions override earlier ones.
165176 // Processing order: with flags -> without flags -> explicit defines.
166177 macros := make (map [string ]string )
@@ -186,6 +197,14 @@ func GenerateMacrosFileContents(buildConfig projectconfig.ComponentBuildConfig)
186197 delete (macros , undef )
187198 }
188199
200+ if len (macros ) == 0 {
201+ return ""
202+ }
203+
204+ lines := []string {
205+ MacrosFileHeader ,
206+ }
207+
189208 // Sort macro names for deterministic output.
190209 macroNames := lo .Keys (macros )
191210 slices .Sort (macroNames )
@@ -215,23 +234,25 @@ func (p *sourcePreparerImpl) postProcessSources(
215234 return fmt .Errorf ("failed to get absolute path for %#q:\n %w" , specPath , err )
216235 }
217236
218- // Compute any synthetic overlays required to load the macros file.
219- macroOverlays , err := synthesizeMacroLoadOverlays (macrosFileName )
220- if err != nil {
221- return fmt .Errorf ("failed to compute macros load overlays:\n %w" , err )
237+ // Compute any synthetic overlays required to load the macros file, if one was written.
238+ if macrosFileName != "" {
239+ macroOverlays , macroErr := synthesizeMacroLoadOverlays (macrosFileName )
240+ if macroErr != nil {
241+ return fmt .Errorf ("failed to compute macros load overlays:\n %w" , macroErr )
242+ }
243+
244+ // Apply those overlays *first*, in sequence.
245+ for _ , overlay := range macroOverlays {
246+ err = ApplyOverlayToSources (p .dryRunnable , p .fs , overlay , sourcesDirPath , absSpecPath )
247+ if err != nil {
248+ return fmt .Errorf ("failed to apply system overlay to sources for component %#q:\n %w" , component .GetName (), err )
249+ }
250+ }
222251 }
223252
224253 // Get the file header overlay.
225254 headerOverlay := generateFileHeaderOverlay ()
226255
227- // Apply those overlays *first*, in sequence.
228- for _ , overlay := range macroOverlays {
229- err = ApplyOverlayToSources (p .dryRunnable , p .fs , overlay , sourcesDirPath , absSpecPath )
230- if err != nil {
231- return fmt .Errorf ("failed to apply system overlay to sources for component %#q:\n %w" , component .GetName (), err )
232- }
233- }
234-
235256 // Apply all overlays in sequence.
236257 for _ , overlay := range component .GetConfig ().Overlays {
237258 err = ApplyOverlayToSources (p .dryRunnable , p .fs , overlay , sourcesDirPath , absSpecPath )
0 commit comments