在 make 函数中使用 eval

using eval inside of make function

(注意——这与我之前的问题类似,但似乎有不同的原因,所以我在这里发布了一个新问题)。

我正在调试一些 makefile,其中散布着一些非常复杂的 eval。我希望能够准确地转储 eval 扩展到的内容,然后调用 evals。我需要这样做,以便我可以轻松地打开 on/off 调试,但我发现函数中 eval 有一些奇怪的行为。我有:

FOO := a:=foo
$(eval $(FOO))
$(info a=$(a))   #a=foo -- OK

define eval_dbg
$(info eval_dbg: running []) #  is "a:=bar"
$(eval $(1))                   # fails - missing seperator...
endef

$(call eval_dbg,a:=bar)    #causes error...
$(info a=$a)

但是,我得到:

a=foo
eval_dbg: running [a:=bar]
test2.mk:17: *** missing separator.  Stop.

是否可以评估调用参数?


** 最小可重现示例:**

tmp> more test3.mk
FOO := a:=foo
$(eval $(FOO))
$(info a=$(a))

define eval_dbg
$(info eval_dbg: running [])
$(eval $(1))
endef

$(call eval_dbg,a:=bar)
$(info a=$a)

all:
        @echo running $@

tmp> make -f test3.mk
a=foo
eval_dbg: running [a:=bar]
test3.mk:10: *** missing separator.  Stop.

tmp> make --version
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for x86_64-unknown-linux-gnu

问题是调用 eval(...) 的结果是空字符串,所以实际上你传递了 call 一个参数——定义的函数 eval_dbg ——包含空格,call 不喜欢空格。

define func_1
$(info hello)
endef

$(call func_1) # this works                                                     

define func_2
$(info hello)

endef

$(call func_2) # this fails 

define func_3
$(info hello)
$(eval a:=b)
endef

$(call func_3) # this also fails

但是没有理由从函数内部调用 eval。如您所示,您可以打印该语句,然后对其调用 eval。或者你可以传递 eval 调用 call:

的结果
define foo_double
$(1):=foo_$(1)$(1)
endef

$(info $(call foo_double,a))
$(eval $(call foo_double,a))

$(info a is $a)

问题是由于 评论 在 "define".

基本上,"define" 与变量赋值相同(换行符除外)。 "Call" 进行扩展,但不进行评估。因此,评论未经评估就进入流 --> 发生错误!

所以寓意:

  1. 定义不是宏;这是一个字符串
  2. 来电不是评价;这是一个扩展
  3. 注释不是空格;他们被评估

更新。事实证明,另一个问题是旧的 make 版本。看起来 v3.81 不能像现代 make 版本那样简单地忽略空格。

额外的 eval 解决了这个问题:

$(eval $(call eval_dbg,a:=bar))