Makefile二次展开:执行转义函数?
Makefile secondary expansion: execution of escaped function?
考虑以下 makefile:
.SECONDEXPANSION:
%.result: jobs/% $$(call get-job,$$<)
echo $^
define get-job
$(shell head -n 1 $(1))
$(shell tail -n +2 $(1))
endef
想法是 jobs/ 下的每个文件都包含一个文件名列表,应该附加到先决条件列表中。
但是,如果我想从现有文件 jobs/xyz 创建 xyz.result,我会得到以下错误消息:
$ make -n xyz.result
head: cannot open 'xyz.result' for reading: No such file or directory
tail: cannot open 'xyz.result' for reading: No such file or directory
head: cannot open 'xyz.result' for reading: No such file or directory
tail: cannot open 'xyz.result' for reading: No such file or directory
make: *** No rule to make target 'xyz.result'. Stop.
我知道 $$<
未设置为我想要的,因为它反映了任何先前规则的先决条件列表。
我不明白的是:
- 在我的理解中,
$$<
应该评估为空字符串(如 official doc 中的示例所示,在第二个 sub-heading 下)。不过这里好像扩展到target的值了(xyz.result)。这是为什么?
- 似乎
get-job
函数被调用了两次(head
和 tail
都叫了两次)。我了解先决条件列表已扩展两次。但是在第一个 运行 中, call
仍然被转义,所以这不是我所期望的。
(也许整个方法都有缺陷,我一开始就不应该(滥用)使用 Makefile 来完成此类任务。)
我不知道为什么 $$<
会这样扩展。
不过,您可以使用 $$*
使您的配置生效:
%.result: jobs/% $$(strip $$(call get-job,jobs/$$*))
echo $^
您需要添加 strip
调用,以便将 call
结果中嵌入的换行符转换为空格。
考虑以下 makefile:
.SECONDEXPANSION:
%.result: jobs/% $$(call get-job,$$<)
echo $^
define get-job
$(shell head -n 1 $(1))
$(shell tail -n +2 $(1))
endef
想法是 jobs/ 下的每个文件都包含一个文件名列表,应该附加到先决条件列表中。
但是,如果我想从现有文件 jobs/xyz 创建 xyz.result,我会得到以下错误消息:
$ make -n xyz.result
head: cannot open 'xyz.result' for reading: No such file or directory
tail: cannot open 'xyz.result' for reading: No such file or directory
head: cannot open 'xyz.result' for reading: No such file or directory
tail: cannot open 'xyz.result' for reading: No such file or directory
make: *** No rule to make target 'xyz.result'. Stop.
我知道 $$<
未设置为我想要的,因为它反映了任何先前规则的先决条件列表。
我不明白的是:
- 在我的理解中,
$$<
应该评估为空字符串(如 official doc 中的示例所示,在第二个 sub-heading 下)。不过这里好像扩展到target的值了(xyz.result)。这是为什么? - 似乎
get-job
函数被调用了两次(head
和tail
都叫了两次)。我了解先决条件列表已扩展两次。但是在第一个 运行 中,call
仍然被转义,所以这不是我所期望的。
(也许整个方法都有缺陷,我一开始就不应该(滥用)使用 Makefile 来完成此类任务。)
我不知道为什么 $$<
会这样扩展。
不过,您可以使用 $$*
使您的配置生效:
%.result: jobs/% $$(strip $$(call get-job,jobs/$$*))
echo $^
您需要添加 strip
调用,以便将 call
结果中嵌入的换行符转换为空格。