I thought I understood that simply-expanded variables got their value once, when the Makefile
is read -- but I've got confused:
var := $$RANDOM
echo:
@echo v1: $(var)
@echo v2: $(var)
With result
$ make
v1: 11478
v2: 24064
So how come the shell env var is referenced twice?
I see that var := $(shell echo $$RANDOM)
don't do the second value assignment -- how is this machinery different?
CodePudding user response:
Simply-expanded variables are MAKE constructs. Indeed, that variable is only expanded one time, by make. But, it expands into a shell variable:
var := $$RANDOM
now the value of the var
variable in make is the static string $RANDOM
and make will never expand it again. You can determine this by doing something like:
var := $(info expanding RANDOM)$$RANDOM
and you'll see it only prints expanding RANDOM
one time.
But, this rule:
echo:
@echo v1: $(var)
@echo v2: $(var)
invokes shell two times and each time passing the static string $RANDOM
, which the shell expands, each time the shell is invoked, and you get different answers. Basically, make is running:
/bin/sh -c 'echo v1: $RANDOM'
/bin/sh -c 'echo v2: $RANDOM'
If you change it to this:
var := $(shell echo $$RANDOM)
Here, make is invoking the shell, one time, and assigning the result of that shell command to the variable var
. So after this, var
contains the literal string 12345
or whatever the result is, not $RANDOM
.
BTW, you should add:
SHELL := /bin/bash
to your makefile, because $RANDOM
is a bash feature that is not available in the POSIX shell, and make always invokes /bin/sh
by default: on some systems /bin/sh
is the same thing as bash but on other systems, it isn't.