I believe a Makefile is worth a thousand words!  

Try out the attached Makefile by simply running `make'.  I hope it
clearly demonstrates why extra care should be taken when using
recursive variables.

Let me know if you need more clarification.

-- 
Bahman


On Wed, 2023-09-13 at 16:48 -0700, Tom Ma wrote:
> Hi gnu make friend,
> 
> I am trying to understand the first flavor of variable - recursively
> expanded variable assignment disadvantages mentioned in gnu make
> manual,
> 
> Another disadvantage is that any functions (see Functions for
> Transforming
> Text
> <https://www.gnu.org/software/make/manual/html_node/Functions.html>)
> referenced in the definition will be executed every time the variable
> is
> expanded. This makes make run slower; worse, it causes the wildcard
> and
> shell functions to give unpredictable results because you cannot
> easily
> control when they are called, or even how many times.
> 
> For the recursively expanded variable assignment  on Transforming
> Text
> functions, it will be executed every time the variable is expanded,
> which
> will cause make run slower.
> Can you give a simple example to make it a little bit more clearer?
> 
> Thanks,
> Tom
#################################################################
# Demonstrating recursive variables - Bahman Movaqar
#################################################################
SHELL := /usr/bin/env -S bash -o pipefail
.DEFAULT_GOAL := all

#################################################################

define a-recursive-var =
$(info 💡 a-recursive-var is computed.)$(strip a-recursive-var)
endef

define a-simple-var :=
$(info 💡 a-simple-var is computed.)$(strip a-simple-var)
endef

.PHONY : demonstrating-text-functions
demonstrating-text-functions :
	@echo \
	;  echo $(@) \
	;  echo '  $(a-recursive-var)' \
	;  echo '  $(a-recursive-var)' \
	;  echo '  $(a-recursive-var)' \
	;  echo '  $(a-simple-var)' \
	;  echo '  $(a-simple-var)' \
	;  echo '  $(a-simple-var)' \
	;  echo

#################################################################

timestamp = $(shell perl -MTime::HiRes=time -E'say time()')

.PHONY : demonstrating-shell-function
demonstrating-shell-function :
	@echo \
	;  echo $(@) \
	;  export ts1='$(timestamp)' \
	;  export ts2='$(timestamp)' \
	;  [[ "$$ts1" == "$$ts2" ]] \
		&& echo "  ✅ ts1 = ts2" \
		|| echo "  ❌ ts1 ≠ ts2" \
	;  echo

#################################################################

.PHONY : all
all : demonstrating-text-functions
all : demonstrating-shell-function

Reply via email to