2

I was looking at another stack overflow question, and they were using, what looks to be undocumented behavior for makefiles... If I have the following Makefile:

X=X 

all:
    @echo $@: $(X)
    $(eval X=Y)
    @echo $@ part2: $(X)

all2:
    @echo $@: $(X)

Then I run:

~> make all2
all2: X
~> make all all2
running all
all: X
all part2: Y
all2: Y

I would have expected the $(eval X=Y) to expand at Makefile parse time, and set the shell variable X to be Y for that line of the recipe (i.e. do nothing). Instead, it seems to be evaluated when the all recipe is run, plus, it seems to set the make variable. I've looked through the make man page, and for online manuals, but I can't find anything that describes this behavior (I'm using GNU Make 4.0). Can someone point me to some documentation describing this, or explain what's going on?

Community
  • 1
  • 1
John
  • 3,400
  • 3
  • 31
  • 47
  • 2
    You may find more information here : http://stackoverflow.com/questions/38224102/make-define-multiple-variables-in-the-same-eval-call . Basically, as said in the GNU make documentation, it's a Makefile syntax part evaluated at the call so it's still a Makefile variable and it is, indeed, evaluated in the target `all` . Here's `eval` documentation : https://www.gnu.org/software/make/manual/html_node/Eval-Function.html – Tim Jul 06 '16 at 20:16

1 Answers1

6

I'm not sure why you would expect either of the things you mention to be true. Maybe you're thinking that this is using the shell eval, somehow? That's not what it's doing, it's using the GNU make eval function, which is discussed here.

Just like any other variable or function, eval appearing in a recipe is not expanded until (and unless) the recipe is invoked because the target is out of date. See How make Reads a Makefile for full details on when variables and functions are expanded.

Second, all make variable assignments set make variables, and only if you export them will they be sent to the shell.

MadScientist
  • 92,819
  • 9
  • 109
  • 136