help-make
[Top][All Lists]
Advanced

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

Re: $(info ...) in variable, with expansion in recipes


From: Philip Guenther
Subject: Re: $(info ...) in variable, with expansion in recipes
Date: Fri, 4 Jul 2014 12:36:55 -0700
User-agent: Alpine 2.11 (BSO 23 2013-08-11)

On Fri, 4 Jul 2014, Yann Droneaud wrote:
> Le vendredi 04 juillet 2014 ? 19:01 +0200, Yann Droneaud a ?crit :
> > Le vendredi 04 juillet 2014 ? 18:24 +0200, Yann Droneaud a ?crit :
> > > I'm a bit puzzled regarding the behavor of make: I don't understand why 
> > > a make function is executed twice when stored in a variable which is 
> > > expanded as part of a recipe.
> > > 
> > > See the following Makefile fragment, as info.mk:
> > >   ifeq ($(V),1)
> > >   Q :=
> > >   else
> > >   Q ?= @
> > >   endif
> > > 
> > >   all:
> > >           $(Q) : $(info 1)
> > >           $(Q)$(RECIPE)
> > >           $(Q) : $(info 3)
> > > 
> > > When make is invoked with
> > > 
> > >   $ $ ./make -f ./info.mk
> > >   1
> > >   3
> > > 
> > > Now, let's put some shell in RECIPE variable:
> > > 
> > >   $ make -f ./info.mk RECIPE='echo 2'
> > >   1
> > >   3
> > >   2
> > > 
> > > Having 2 printed after 3 is OK here: $(info ...) in the recipe were 
> > > expanded before each command were feed to the shell for execution.
> > > 
> > > Now, try to get 2 printed between 1 and 3:
> > > 
> > >   $ ./make -f ./info.mk RECIPE=': $(info 2)'
> > >   1
> > >   2
> > >   3
> > >   2
> > > 
> > > This way, 2 is printed twice. The second times seems to happen just
> > > before passing to the shell the line where the variable is expanded.
...
> If the variable is defined as a simply defined one ('simple' flavor) 
> with := operator on make command line, the results are a bit weird:
> 
>   $ ./make -f ./info.mk V=1 RECIPE:=': $(info 2)'
>   2
>   1
>   3
>   : 
>   : 
>   : 

This combination of behaviors is caused by the requirement that variables 
set on the make command-line are exported to the environment for commands 
by default.

For a normal recursively expanded variable, the value placed in the 
environment has to be expanded completely before being placed in the 
environment.  That expansion happens at the last moment, after the 
commands are expanded but before the shell is invoked.  That explains the 
original example.

This can be confirmed by tell make that the RECIPE variable doesn't need 
to be exported.  If you add this line to the Makefile:
    unexport RECIPE

then the second '2' output goes away.


So what about the simply expanded variable case, RECIPE:=': $(info 2)' ? 
For a simply expanded variable, it is expanded when the assignment occurs.  
For a command-line assignment, that's very early in the processing, as 
Yann deduced:

> But they make sense: as a simply expanded variable, RECIPE should get
> its value at the time it's defined, so having 2 printed as soon as make
> start processing seems correct and logical.


At that point, the variable has now been expanded completely, so when time 
comes to stuff it into the environment there's no additional output.


Philip Guenther




reply via email to

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