[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