=

BAR = banana

FOO = one $(BAR), two $(BAR)s

BAR = guava

FOO

FOO

FOO

FOO

TODAY = $(shell date +%d/%m/%y)

TODAY

BAR = banana

FOO := one $(BAR), two $(BAR)s

BAR = guava

FOO

one banana, two bananas

one guava, two guavas

:=

FOO

BAR

banana

FOO

expensive-to-calculate

FOO = $(eval FOO := expensive-to-evaluate)$(FOO)

FOO

$(eval)

expensive-to-evaluate

FOO

NOW

$(info)

. And calls to

$(flavor)

to show when

NOW

changes from recursive to simple.





$(info Start Parse)





NOW = $(eval NOW := $(info Expand NOW)$(shell date -u))$(NOW)





.PHONY: all foo





$(info End Parse)

Start Parse

End Parse

Expand NOW

foo / recursive / Sat Jul 23 15:01:15 UTC 2016 / simple

all / simple / Sat Jul 23 15:01:15 UTC 2016 / simple

NOW

$(info Start Parse)





make-lazy = $(eval $1 = $​$(eval $1 := $(value $(1)))$​$($1))

NOW = $(info Expand NOW)$(shell date -u)

$(call make-lazy,NOW)





.PHONY: all foo









$(info End Parse)





Just $(call) make-lazy on any recursive variable to make it lazy.

GNU make has two 'flavors' of variable:and. Everyone is familiar the the recursive style (which usesfor definition):The value ofis determined each timeis used. In a large Makefile that can mean thatis expanded over and over again. If expandingis an expensive operation then determining its value each time can slow down the Makefile. For example,would be very expensive is it would shell out to run date every timeis used (and might have the strange effect of returning different dates if you run your make near midnight).(I've written about that before and in my book on GNU make The other flavor of make variable is: its value is fixed the moment it's defined:Thereis set toand not(as was the case above) because the right hand side of theis expanded whenis being defined andhas the valueat that point.But suppose you wanted a mixture of the two: a variable that is only ever expanded once and only expanded if it is used. This might be useful if the variable was used rarely as part of the build and was expensive to expand.You can concoct a recipe for that like this. Suppose you want to define a variableto have valuethen you can use the following pattern:It's initially a recursive variable and so the right-hand side is not expanded until it is used. But the first time it is usedis redefined (by the) and becomes a simple variable with the value ofHaving become a simple variable it's possible to return its value (note that ifwas still recursive it would not be allowed to reference itself like that).You can see that in action with the following Makefile. To make it clear whenis actually expanded I've added a call toWhich will outputThe one gotcha with this is that you need to be sure that whenis expanded any variable it depends on have the values you expect.It's possible to wrap that up in a function like this: