Description of problem: When using constructs like "%if %{with ...}", rpmbuild doesn't expand constructs like these (perhaps it assumes the macros are already set): %{!?some_macro: %define some_macro ...} Version-Release number of selected component (if applicable): rpm-build-4.4.2.3-2.fc9.x86_64 How reproducible: Always Steps to Reproduce: 1. rpmbuild -bp broken.spec Actual results: [...] + echo %some_macro %some_macro [...] Expected results: [...] + echo this works this works [...] Additional info: I'll attach two spec files, "broken.spec" to demonstrate the problem using this construct: %{!?some_macro: %define some_macro this works} ... and "works.spec" which works around the problem using this construct: %if %{undefined some_macro} %define some_macro this works %endif
Created attachment 312437 [details] spec file which exhibits the broken behavior
Created attachment 312439 [details] spec file which works around the broken behavior
Did this example ever work or is it just broken in recent rpm version?
Try %{!?some_macro: %global some_macro ...}
Is this another workaround or are there errors in the attached spec file (and this is the correct way to do it)?
All depends on POV. If using %global rather than %define "works", the issue is a fundamental design flaw with macros that can't ever be corrected. The cure would be far worse than the disease. Much like automatic stack storage in C, macros have a scoping level, and are automatically undefined when they go out of scope. %global rather than %define within a %{!?test:...} expression sets the macro at level 0 rather than at level 1. In most cases the difference between %global and %define doesn't matter. But the problem shows up from time to time. There's a bugzilla report from Axel abt 2 years ago last time I recall the issue being reported. The issue is described fully there. Does using %global rather than %define fix your issue or not?
Interesting background -- and using %global instead of %define indeed works. If this is really unfixable, I can live with using %global as a workaround. We should just update the Python Packaging documentation in the Fedora wiki accordingly.
AFAIK, using %global rather than %define is already suggested somewhere deep in the bowels of the Fedora packaging wiki, added as a side effect of Axel's bug report 2 years ago. Changing %define to be a synonym for %global could be attempte. But that change is most definitely a feature regression that can/will subtly break parameterized macros and more. Without explicit conformance & regression tests for macro behavior, that's a really risky change. Which is why I never attempted a fix. (aside) Note that there's another fundamental design flaw in macros, passing expanded (or not) macros as arguments to %foo() parameterized macros. The expectation is that the expansion, not the unexpanded macro expression, is passed but in fact the arguments to parameterized macros are unexpanded. One can add explicit %{expand:...} constructs to solve the issue if necessary. But the behavior is flawed imho.
Yup, rpm is behaving as intended, even if not necessarily as expected :) Fedora documenation now recommends %global over %define (but misses out some other details...)