11

在手册中:

eval 函数非常特殊:它允许您定义非常量的新 makefile 结构;这是评估其他变量和函数的结果。eval 函数的参数被扩展,然后扩展的结果被解析为 makefile 语法。

重要的是要意识到 eval 参数被扩展了两次。首先由 eval 函数,然后在将其解析为 makefile 语法时再次扩展该扩展的结果。这意味着您在使用 eval 时可能需要为“$”字符提供额外的转义级别。

“扩大了两次”让我感到困惑。

例如,我创建了一个 makefile :

define func
    tmp = $(OBJPATH)/$(strip $1)
    objs += $$(tmp)
    $$(tmp) : $2
        gcc $$^ -o $$@
endef

all : foo

$(eval $(call func, foo, 1.c))    

eval 函数将如何扩展?

4

2 回答 2

24

理解它的最简单方法是将 eval 替换为 info:

$(info $(call func, foo, 1.c))

这将显示第一次扩展的结果作为输出,因此您可以看到 make 实际解析的内容。您没有提供 OBJPATH 变量的值,但如果是obj例如,那么在您的情况下,(调用函数的)第一次扩展会导致:

tmp = obj/foo
objs += $(tmp)
$(tmp) : 1.c
    gcc $^ -o $@

然后 make 解析器将对此进行评估,并在此过程中再次对其进行扩展,因此诸如此类的内容$(tmp)将被扩展。

于 2012-05-03T18:09:45.517 回答
3

这对我来说一直是个问题,但我找到了一个很好的解决方法。就我而言,它与 AWS docker login 有关。我以前在我的 shell 脚本中有:

eval $(aws ecr get-login --region eu-west-1 --no-include-email --profile someprofile)

但是当把它放进去时Makefile它不起作用。解决方法是将行更改为:

$$(aws ecr get-login --region eu-west-1 --no-include-email --profile someprofile)

于 2021-02-09T09:42:33.433 回答