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: Yann Droneaud
Subject: Re: $(info ...) in variable, with expansion in recipes
Date: Fri, 04 Jul 2014 19:20:27 +0200

Le vendredi 04 juillet 2014 à 19:01 +0200, Yann Droneaud a écrit :
> Le vendredi 04 juillet 2014 à 18:24 +0200, Yann Droneaud a écrit :
> > Hi,
> > 
> > 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.
> > That can be checked with
> > 
> >   $ ./make -f ./info.mk V=1 RECIPE=': $(info 2)'
> >   1
> >   2
> >   3
> >   : 
> >   2
> >   : 
> >   : 
> > 
> > So the second 2 (!) seems to be reported after recipe line
> > 
> >     $(Q) : $(info 1)
> > 
> > is executed by the shell, but before this recipe line
> > 
> >     $(Q)$(RECIPE)
> > 
> > is executed by the shell.
> > 
> > As I haven't done my homework, I don't know if it's an expected 
> > documented behavor. But it's a pity it behave this way.
> > 
> > Is there any workaround to have 2 printed only one ?
> > 
> > BTW, it seems to happen only with $(info ...), as it would be very bad
> > if other functions having side effect would be called twice. See for
> > example:
> > 
> 
> I've found a workaround, but such workaround so counter-intuitive that's
> demonstrate there's really something wrong about having $(info ...) in 
> a variable which is expanded as part of a recipe. See this new makefile
> fragment, info-empty.mk, which use $(if ...):
> 
>   ifeq ($(V),1)
>   Q :=
>   else
>   Q ?= @
>   endif
> 
>   empty :=
> 
>   all:
>       $(Q) : $(info 1)
>       $(Q)$(if $(empty),$(RECIPE))
>       $(Q) : $(info 3)
> 
> $(if ...) is said to not expand one of its arguments, so my variable
> RECIPE containing  $(info ...) should not be expanded, as $(empty) is 
> always false.
> 
> Let's try:
> 
>   $ ./make -f ./info-empty.mk RECIPE=': $(info 2)'
>   1
>   3
>   2
> 
> And with V=1:
> 
>   $ ./make -f ./info-empty.mk V=1 RECIPE=': $(info 2)'
>   1
>   3
>   : 
>   2
>   : 
> 
> $(info 2) is only evaluated once ... but it should never be evaluated as
> far as I understand how make proceed to variable expansion and function
> execution.
> 
> What do you think of this ?
> 

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
  : 
  : 
  : 
  $ ./make -f ./info-empty.mk V=1 RECIPE:=': $(info 2)'
  2
  1
  3
  : 
  : 

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.

In the other hand having the variable RECIPE defined in the process
environment (so as a simply expanded variable) prior make invocation, 
the behavor is different.

  $ RECIPE=': $(info 2)' ./make -f ./info.mk V=1 
  1
  2
  3
  : 
  : 
  : 
  $ RECIPE=': $(info 2)' ./make -f ./info-empty.mk V=1 
  1
  3
  : 
  : 

It's somewhat what I've expected in the first place, but regarding the 
other results, I'm not convinced to have a correct behavor: RECIPE has
simple "flavor", so it shouldn't be recursively expanded when 
referenced the recipe.

I'm a bit lost ...

Regards.

-- 
Yann Droneaud
OPTEYA





reply via email to

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