GNU Make:如何在$(eval)中调用$(通配符)

时间:2010-03-10 23:39:53

标签: makefile eval gnu-make

我正在尝试为我的Makefile创建一个通用的构建模板,就像他们在eval documentation中讨论一样。

我似乎无法在eval中使用通配符函数。我遇到问题的基本代码看起来像这样。

SRC_DIR = ./src/

PROG_NAME = test

define PROGRAM_template
  $(1)_SRC_DIR = $(join $(SRC_DIR), $(1)/)
  $(1)_SRC_FILES = $(wildcard $$($(1)_SRC_DIR)*.c)
endef

$(eval $(call PROGRAM_template, $(PROG_NAME)))

all:
    @echo $(test_SRC_DIR)
    @echo $(test_SRC_FILES)
    @echo $(wildcard $(wildcard $(test_SRC_DIR)*.c)

当我用make运行make时,输出是

./src/test

[correct list of all .c files in ./src/test/]

基本上,PROGRAM_template中的通配符调用没有像我预期的那样被评估。通话结果为空列表 正在正确评估连接调用。

那么,我做错了什么?我猜是

$$($(1)_SRC_DIR) 

不正确,但我无法找到正确的方法。

修改 一旦解决了这个问题,我花了很长时间才能用eval来解决另一个问题。 我把它作为一个新问题发布在 Workaround for GNU Make 3.80 eval bug

1 个答案:

答案 0 :(得分:10)

使用eval时,您需要对所有函数和变量进行双重转义。在大多数情况下,需要双重转义的唯一内容是函数参数(因为call函数将完全展开它们)。在这种情况下,您在技术上也不需要双重转义joinSRC_DIR,但如果您在使用{{1}时总是双重转义所有变量和函数,它将简化您的生活}。

您需要双重转义的原因是,在使用eval时,扩展会发生两次eval函数本身执行扩展,然后当块最终被解析为makefile语法时(即实际评估它时),再次 进行扩展。

您编写的方式,在字符串文字eval上调用wildcard。如果您愿意,可以在版本中将$( test_SRC_DIR)*.c替换为wildcard并查看会发生的情况,从而自行查看。

你需要推迟实际调用info直到第二次扩展,以便它的参数是扩展 wildcard的结果。

试试这个:

$(test_SRC_DIR)

编辑:发布此内容后,我认为我最好先测试一下,以确保它确实有效。在这样做时,我发现了另一个问题。在调用函数时,应避免在逗号和参数之间放置空格。它会将一个文字空格字符添加到传递给函数的参数之前,并导致意外的结果。我已经删除了我的版本中函数调用中逗号之后的空格(虽然这对于SRC_DIR = ./src/ PROG_NAME = test define PROGRAM_template $(1)_SRC_DIR = $$(join $$(SRC_DIR),$(1)/) $(1)_SRC_FILES = $$(wildcard $$($(1)_SRC_DIR)*.c) endef $(eval $(call PROGRAM_template,$(PROG_NAME))) all: @echo $(test_SRC_DIR) @echo $(test_SRC_FILES) @echo $(wildcard $(test_SRC_DIR)*.c) 的调用不是问题,我也删除了那里的空间,因为这是一个很好习惯进入)。