Update advice on creating specfile macros #1454
No reviewers
Labels
No labels
announce
bootstrap
Closed As
accepted
Closed As
duplicate
Closed As
exceptionexpired
Closed As
fixed
Closed As
invalid
Closed As
nothingtodo
Closed As
permanentexception
Closed As
rejected
Closed As
temporaryexception
Closed As
wontfix
cmake
committee
draftneeded
hasdraft
meeting
meson
needinfo
Priority
In Committee
Priority
Needs Review
Priority
Waiting For Reporter
rust
writeup
No milestone
No project
No assignees
5 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
packaging/guidelines!1454
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "rpm-macro-guidelines"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The guideline to use
%globalin preference to%definewasdescribed by an RPM developer as "bad advice that spread far and
wide". This change completely reverses that advice, instructing
packagers to use
%defineby default and%globalonly whenneeded.
This PR currently contains just the guidelines-text change. I'm hoping to also update many of the specfile templates and other bits of code that use
%global(there are currently over 400 matches for%globalin the packaging guidelines source), but that's in part pending an answer to my question over in #1449. I wanted to get this opened ASAP so everyone could decide how they feel about the wording, though.Fixes #1449
i out a word, that should say "MAY be updated..."
1 new commit added
Add missing wordI am not a huge fan of introducing the term "variables" into this. They are macros, not variables.
Just making sure I understand this correctly,
%globals are expanded once at definition time,%defines are expanded on every use?Assuming this is correct, this advice might be too strong:
There will be instances where the time of evaluation will make a difference (for example, macros could be pulled in as BuildRequires, but not in Requires, leading them to be undefined at runtime), or macros that shell out and query the environment - and I don't think these are really that rare.
And assuming that I understand this correctly, it might be better to say something like
%definewhen it doesn't matter when the macros is expanded (or how often), i.e. usually for simple text replacements%globalwhen it does matter when / how often expansion happens , if the expansion involves some sort of "expensive computation", or if the expansion relies on things that are only available inside the build environmentTL;DR: I don't think we can just flip the "use %global instead of %define" rule around and don't expect things to break in funny ways.
@decathorpe
Broadly, yes, but I'm not sure how things like shell invocations play into that — just because
%definemacros are lazily expanded, doesn't necessarily mean that a%()subshell invocation will be re-executed at each use. (Doesn't mean that it won't, either, which is why I put that question to @pmatilai in #1449 -- but he hasn't responded yet, so I'll open an issue in the RPM upstream repo to clear that point up.)The RPM macro docs do mention that
%globalis in part "useful to avoid re-expansion of expensive macros", but doesn't elaborate on what exactly that means at all.But beyond that, situations like this:
...are where
%defineis most preferable to%global, because a%definemacro will resolve even if some of its component macros are defined after it... with%global, the moment the statement is processed you've lost your chance to define/redefine any of the macros used in that statement.With
%define, macros are expanded at time of use, yes... but those uses still occur at build-time. No%define'd macros should survive to runtime unless they're explicitly escaped via%%invocations.IOW, if I use a
%definemacro in a%preunscript, the "time of use" is when that%preuncode is processed into a script by rpmbuild as it's processing the specfile. What gets written into the RPM metadata is a static script with all of the macros expanded. There's no runtime dependency on the macros.Ditto if I use a macro in a
Version:orProvides:or etc. line in the specfile... the value that's stored is the expansion of that macro, regardless whether it's a%globalmacro or a%definemacro. The only difference is that the%definemacro is expanded when theVersion:orProvides:line is processed, whereas the%globalmacro was expanded way back when it was created.Question posted to the RPM repo's Q&A area: https://github.com/rpm-software-management/rpm/discussions/3727
Apologies for being slow to respond to this stuff.
I'd recommend dropping the SHOULD/MAY language entirely because recommending one over the other doesn't make sense. It's like a recommendation between a spoon and a shovel: they do kinda similar things, but sometimes you need one and sometimes the other, and there's no universal recommendation you could make.
I think we should just help packagers make informed choices. Explaining the actual difference like here is good, practical examples of when to use each should help more.
For a practical rule of thumb, something like "Use %global for unchanging global values, otherwise use %define."
@pmatilai
Well, they're guidelines, not RPM documentation — being prescriptive is sort of the entire point. I agree that including an explanation of the two is useful, but the guidelines are there specifically to provide rules for packagers to follow.
The rule can be (and will probably have to be) some form of, "packagers SHOULD use whatever makes the most sense for a given case" (heck, that could even be a MUST rule), but there's still gonna be a rule.
(And speaking of RPM documentation, I think this stuff could be covered in more detail in the actual RPM documentation — which, as I mentioned, doesn't really ever come out and say that shell invocations and other operations will be re-executed on every expansion of a
%definemacro — but that's a conversation for the PR against https://github.com/rpm-software-management/rpm/blob/master/docs/manual/macros.md that I expect I'll be talked into submitting 😉 )See, that's a pretty big departure from where this all started, because most of our macros ARE unchanging global values. Now, it's likely that's more out of necessity than anything else, since we scared people off of
%definefor so long that%globalis all they know. As a result, they often tend to treat all macros as if they can only be unchanging global values.(Which sort of explains, but doesn't, the unnecessary nonsense
%global ... %{expand: ... }that started all this. The only explanation I can give for that is that we've so brainwashed our packagers into%globalbeing the only way to define a macro, they no longer remember — or never knew — what it means relative to%define.)So I definitely agree that helping packagers better understand the difference is useful.
I also agree that practical examples demonstrating situations that would favor either
%globalor%define(like the ones I used in my Q&A post, as a starting point) would also be useful... but in the back of my mind it feels wrong if we end up having better examples than the real docs, so that's probably (also) another topic for thatmacros.mdPR. 😀We talked about this again, in the meeting this week, and one idea that came up was to try to move the real part of the documentation to upstream/rpm and then the Fedora docs could just say something like "use define/global appropriately as needed, see this link to the upstream rpm docs on how they work"
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.