help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: second-expansion prerequisite


From: Paul Smith
Subject: Re: second-expansion prerequisite
Date: Sat, 30 Oct 2010 09:40:05 -0400

On Sat, 2010-10-30 at 13:50 +0800, gaoyong pan wrote:
> I have below makefile and its output,
> ------------------------------------------------
> fp := first_prerequisite
> 
> all: $(fp) $(sp)                      <------(1)
>   $(info $+)                          <------(2)
>   $(info $(sp))                      <-------(3)
> 
> $(fp) $(sp):;
> 
> sp := second_prerequisite     <-------(4)
> ------------------------------------------------
> first_prerequisite
> second_prerequisite
> make: `all' is up to date.
> ------------------------------------------------
> 
> the $(sp) is undefined on line (1), so it is empty and the target
> "all" has only one prerequisite $(fp), what I expect are two $(fp) and
> $(sp). I know this can be fixed by moving line (4) above line (1).
> However, the line (3) outputs the correct defined variable $(sp) value
> "second_prerequisite", I'm wondering why "make" works  in this way?

Variables are expanded when they are needed by make, not necessarily
when they appear in the makefile.  In some cases (such as target and
prerequisite lists) the variable is expanded immediately, as the
makefile is read in.  In other cases (such as in recipes) the variable
is not expanded when the makefile is read in, but is deferred until the
rule is actually run.  This is what you're seeing.

The GNU make manual has a section "How make reads a makefile" that
explains this with more detail.

> is this related with the second expansion, if so, how I can let make the
> prerequisite $(sp) expansion later?

The short answer is that you can't.  Prerequisites are always expanded
when the rule is read.  You can, of course, rewrite your makefile like
this:

        fp := first_prerequisite
        all: $(fp)
                ...

        sp := second_prerequisite
        all: $(sp)

and it is exactly equivalent.

The longer answer is that you can use the .SECONDEXPANSION target to
delay expansion, but you have to change your rule, like this (note the
double-$):

        .SECONDEXPANSION:

        all: $(fp) $$(sp)
                ...

Note that this has a performance impact on your makefile, and is not
portable.

Far simpler is just to ensure that your variables are defined before the
rule.

-- 
-------------------------------------------------------------------------------
 Paul D. Smith <address@hidden>          Find some GNU make tips at:
 http://www.gnu.org                      http://make.mad-scientist.net
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist




reply via email to

[Prev in Thread] Current Thread [Next in Thread]