如果我在gnu makefile的顶部有以下内容:
$(if _,a:=1)
$(info a=$a)
编译失败(make-3.81: *** No rule to make target '=1', needed by 'a'. Stop.
;如果排除冒号,则*** missing separator. Stop.
)。我知道我可以使用eval
来解决这个问题,但是我不明白为什么需要这样做。
a:=1
,进行解析并将a
设置为1
吗?
答案 0 :(得分:0)
在您的情况下,https://coderwall.com/p/ewxn9g/storing-and-retrieving-objects-with-localstorage-html5
函数的值作为第二个参数(if
),但此函数不作为make变量赋值。对于您的make版本,这已成为规则。这可能是由于make在语法上解析makefile的方式所致。它不认为此a:=1
语句可以是变量赋值,因为(在扩展之前)它看起来好像都不是有效的make变量赋值。因此,if
语句得到了扩展,但是对于将结果视为变量赋值来说,现在为时已晚。
您可以使用:
if
或:
a := $(if _,1)
或:
ifneq (_,)
a := 1
endif
或:
$(if _,$(eval a := 1))
后两种形式之所以起作用,是因为根据定义,$(eval $(if _,a := 1))
函数的自变量扩展结果将作为纯make语句处理。
答案 1 :(得分:0)
我不明白为什么要这么做
嗯,就是这样的设计。
评估过程始终执行(递归)扩展(“初始评估”可通过=
有效地停止后续扩展,即“惰性分配”),但是扩展过程从不进行评估,除非它是明确指出了这一点(基本上,$(eval ...)
是从扩展转换为评估的命令)。
考虑一下:
x := 0
y := 1
# z is set to "y<space><equal><space><dollar>x"
z = y = $x
# [0] [1] [y = $x]
$(info [$x] [$y] [$(value z)])
# error as "y = $x" will not be re-evaluated
#$z
# effectively sets y to "0"
$(eval $z)
# [0] [0] [y = $x]
$(info [$x] [$y] [$(value z)])
从制造商的角度来看,$(if cond,x=y)
与$z
并没有太大的区别---它已扩展但未评估。不管它站在哪里。只需将$(...)
形式的任何内容都视为“数据”,而不是“代码”。