Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Makefile GNU Make:如何在$(eval)内调用$(通配符)_Makefile_Eval_Gnu Make - Fatal编程技术网

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

Makefile GNU Make:如何在$(eval)内调用$(通配符),makefile,eval,gnu-make,Makefile,Eval,Gnu Make,我正在尝试为我的Makefiles创建一个通用的构建模板,就像他们在文章中讨论的那样 我似乎无法让通配符函数在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

我正在尝试为我的Makefiles创建一个通用的构建模板,就像他们在文章中讨论的那样

我似乎无法让通配符函数在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时,输出是

./src/test

[correct list of all .c files in ./src/test/]
基本上,PROGRAM_模板中的通配符调用并不像我预期的那样被评估。呼叫结果为空列表。
不过,正在正确评估加入调用

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

$$($(1)_SRC_DIR) 
不正确,但我想不出正确的方法

编辑 一旦解决了这个问题,我很快就遇到了eval的另一个问题。 我把它作为一个新问题发布在

使用
eval
时,您需要对几乎所有函数和变量进行双重转义。在大多数情况下,唯一不需要双重转义的是函数参数(因为
调用
函数将完全扩展它们)。在这种情况下,从技术上讲,您也不需要双重转义
join
SRC_DIR
,但如果您在使用
eval
时总是双重转义所有变量和函数,则会简化您的生活

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

按照您编写的方式,
通配符
在字符串literal
$(test\u SRC\u DIR)*.c上调用。如果您愿意,您可以通过在您的版本中将
通配符
替换为
信息
来亲自查看这一点,并查看发生了什么

在第二次扩展之前,您需要推迟实际调用
通配符
,以便它的参数是
$(test\u SRC\u 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)

编辑:发布这篇文章后,我想最好对它进行测试,以确保它确实有效。在这样做的过程中,我发现了另一个问题。调用函数时,应避免在逗号和参数之间加空格。它导致在传递给函数的参数前面加上一个文本空格字符,并导致意外结果。在我的版本中,我删除了函数调用中逗号后的空格(虽然这对于调用
join
来说不是问题,但我也删除了空格,因为这是一个好习惯)。

谢谢!我正要评论它不起作用,然后我回来看了你的编辑。看起来行$(1)\u SRC\u DIR=$$(join$$(SRC\u DIR),$(1)/)的工作方式与我的相同,但是对于$(通配符)行,您需要$$。@bengineerd:是的,我已经澄清了我的答案。您不需要在
join
SRC_DIR
上使用双转义符,因为这些转义符只需一次扩展即可完全扩展。但是,就像我说的,总是使用双越狱让生活更容易。当不需要它们时,它们不会伤害任何东西。