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: Etan Reisner
Subject: Re: $(info ...) in variable, with expansion in recipes
Date: Fri, 4 Jul 2014 15:54:36 -0400

Variables from the environment sort of need to be recursively expanded
for commands or other variable references in them to work. (I suppose
they could be simply expanded if make expanded them immediately but
that doesn't match with your output.)

    -Etan

On Fri, Jul 4, 2014 at 1:20 PM, Yann Droneaud <address@hidden> 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 :
>> > 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
>
>
>
> _______________________________________________
> Help-make mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/help-make



reply via email to

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