[Fedora-packaging] Correction to guidelines on %define vs %global
Panu Matilainen
pmatilai at laiskiainen.org
Tue May 26 09:38:03 UTC 2009
On Wed, 20 May 2009, Toshio Kuratomi wrote:
> On 05/20/2009 03:23 AM, Panu Matilainen wrote:
>>
>> Apologies for missing this when the recommendation of %global over
>> %define in Fedora guidelines was being discussed, but better late than
>> never...
>>
>> https://fedoraproject.org/wiki/Packaging/Guidelines#.25global_preferred_over_.25define
>>
>> says "The two macro defining statements behave the same when they are a
>> the top level of rpm's nesting level" but this is not correct:
>>
>> The body of a %global macro is expanded at definition time, whereas the
>> body of a %define is expanded only when used. For many uses it doesn't
>> make any difference but identical they are not, even on top level - for
>> example see the attached example spec:
>>
>> $ rpmbuild -bp macroex.spec 2>/dev/null|grep ^case
>> case1: first - second
>> case2: second - %{xxx}
>>
>> Another example of this difference (in case of parametrized macros):
>> https://bugzilla.redhat.com/show_bug.cgi?id=495658
>>
>
>
> Hi Panu, How does this look? (Note, I haven't tested any of this code yet as
> I'm running out the door. I wrote it just from how I understand your message
> and bz#495658). Also note that I don't know what causes rpm to clear the
> %defines that have been defined. If you can fill that in that would be
> great. If it's too complex, we can figure out some way to rephrase around
> it.
>
> """
> %global and %define are both used to define macros inside rpm spec files. We
> generally prefer using %global over %define.
>
> %define created macros when they are used in nested macro expansions (like in
> %{!?foo: ... } constructs theoretically only lasts until the end brace
> (local scope), while %global definitions have global scope. However, rpm
> currently doesn't clear the scope for the macros unless [Accurate information
> needed here]. So %define'd macros often last throughout a spec file.
> However, when they don't, it's often non-obvious why the spec file is failing
> as the failure is caused by something changing in another part of the spec
> file.
Locally scoped macros get freed (well, popped) on exit from parametrized
macros - think of local variables in a function. The conditional construct
%{!?bar: %define bar defined}
is the special case where the define ends up on non-global scope but
doesn't get freed immediately as this is not a parametrized macro. Note
"immediately": it will get freed eventually if a "call" to parametrized
macro happens:
---
%prep
%define myecho() echo %1 %2
%{!?bar: %define bar defined}
echo 1: %{bar}
%{myecho 2: %{bar}}
echo 3: %{bar}
---
gives:
1: defined
2: defined
3: %{bar}
but if you use "%{!?bar: %global bar defined}" you get what you expect.
I'm not sure if explaining details of such quirks of rpm macro language
really belongs to packaging guidelines, to put it simply:
Inside %{ } blocks you need to use %global to define global macros.
This is not entirely unlike python variable scoping: by default variables
only exist in the scope (local or global) they are created, unless
"global" statement is used to force glocal scope.
> %global has another major difference from %define that can cause problems
> when you first write the macro. %global is evaluated at the time that it is
> written whereas %define is evaluated separately everytime it occurs in a spec
> file. As an example, if you do the following in a spec file::
[snip]
Again I doubt spelling out the crazy details is terribly useful, the rules
are basically:
- Always create parametrized macros with %define.
- Inside %{ } blocks you need to use %global to define global macros.
- %define'd macro is evaluated at time of use, %global macro is evaluated
at time of definition (otherwise it might have references to macros
that have gone out of scope at time of use)
- Panu -
More information about the Fedora-packaging
mailing list