bug-make
[Top][All Lists]
Advanced

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

Re: Difficulties from the combination of functions "call" and "eval"


From: Philip Guenther
Subject: Re: Difficulties from the combination of functions "call" and "eval"
Date: Sun, 18 Jan 2015 13:08:45 -0800

To home in on one key point here...


On Sun, Jan 18, 2015 at 4:31 AM, SF Markus Elfring
<address@hidden> wrote:
...
>>> Lines 183 - 203:
>>> define RESULT_CHECK
>>>         for part in $(1); do \
>>> if test "x$$(< $$part)" != "x0"; then \
>>> $(PRINTF) "$$(TEXT3)" '$$part'; \
>>> exit 12; \
>>> fi; \
>>> done \
>>> && $$(TOUCH) '$(2)'
>>> endef
>>
>> That looks like it expands to shell text when used with $(call), so
>> just call it in a recipe!
>
> Yes. - The evaluated variable should produce shell commands for recipes.
> I try to reuse it as a subfunction.

You use the word "evaluated" there, which I think reflects an
incorrect view of make's operation. To define the words as they're
used in the make documentation:

-  make _expands_ variables and functions, as marked with a leading
dollar-sign.  This
-  make _executes_ recipes and the argument of the $(shell) function
by passing the _expanded_ text to the shell
-  make _evaluates_ the its own input, the makefile, files that it
includes, the argument of the --eval CLI option, and the _expanded_
argument to the $(eval) function

You do not need $(eval) to get expansion to do its job of creating the
final string to pass to the shell in a recipe, for example.

define STUFF
# some shell commands here
sort inputs | uniq -c >outputs
endef

define MORESTUFF
# do something, then do STUFF
create_inputs >inputs
${STUFF}
endef

all:
        ${MORESTUFF}

When 'all' is built, ${MORESTUFF} will be expanded (which will involve
expanding the ${STUFF} inside it) to get a final string, which will
then be passed to the shell.  No need for ${STUFF} or ${MORESTUFF} to
explicitly say "execute this" or "evaluate this".

That's true even when you use $(call):

# Generate file $2 from file $1
define STUFF
# some shell commands here
sort $1 | uniq -c >$2
endef

# Generate $1
define MORESTUFF
# do something, then do STUFF
create_inputs >inputs
$(call STUFF,inputs,$1)
endef

all:
        $(call MORESTUFF,output)

When building 'all', make will expand $(call MORESTUFF,output) by
temporarily setting $1 to 'output' then expanding MORESTUFF.  The
$(call STUFF,inputs,$1) inside that will temporarily override that by
setting $1 to 'inputs' and $2 to 'output' then expanding STUFF.  The
result will be the same as the earlier example.


That distinction between expansion, execution and evaluation make sense?


Philip Guenther



reply via email to

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