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:01:39 +0200

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 ?

Regards.

-- 
Yann Droneaud
OPTEYA





reply via email to

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