简体   繁体   中英

makefile evaluation of variables in template call

Consider this simple makefile that does very little:

define template
copy      := $(1)
$(info $(1) $(copy))

.PHONY    : rule_$(1)
rule_$(1) : VAR := $(1)
rule_$(1) :
    @echo $@ $(VAR)

all       : rule_$(1)
endef

$(foreach mode,DEBUG OPT, \
    $(eval $(call template,$(mode))))

.PHONY : all 
.DEFAULT_GOAL := all 

I thought that this would create two rules, rule_DEBUG and rule_OPT , whose recipes would echo their names and arg. Furthermore, I thought that the info line would just print DEBUG DEBUG and then OPT OPT . However, I am wrong on both accounts. The info lines log:

DEBUG 
OPT DEBUG

And when I run make , I get back nothing but empty lines. If I run make -p , I do see this for rule_OPT :

rule_OPT:
#  Phony target (prerequisite of .PHONY).
#  Implicit rule search has not been done.
#  Implicit/static pattern stem: `'
#  File does not exist.
#  File has been updated.
#  Successfully updated.
# automatic
# @ := rule_OPT
# makefile (from `makefile', line 10)
# VAR := OPT
# automatic
# % := 
# automatic
# * := 
# automatic
# + := 
# automatic
# | := 
# automatic
# < := 
# automatic
# ^ := 
# automatic
# ? := 
# variable set hash-table stats:
# Load=9/32=28%, Rehash=0, Collisions=1/12=8%
#  recipe to execute (from `makefile', line 10):
        @echo  

Looks like @ and VAR have the values I want and expect - but why doesn't it echo correctly? It looks like if I have the recipe:

rule_$(1) :
    @echo $$@ $$(VAR)

That echos what I want, but I am still not sure how to info the copy . Why?

The $(info) output issue is what I explained in the comments on this answer of mine. You have an evaluative order problem. The assignments in the define aren't happening until the define expansion is processed by eval so your assigned variable value isn't visible until later. You need extra eval 's or post- eval expansion to do that.

Either

$(eval copy      := $(1))

in the template or splitting up the contents into multiple defines.

The problem with @echo $(VAR) is the same thing. That is being expanded by the eval of the define 's expansion and $(VAR) is unset at that point so you need $$(VAR) in the template to have a literal $(VAR) in the expanded recipe so that it works correctly and recipe execution time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM