我有以下代码:
foo:
touch foo
$(foreach f, $(shell ls | grep foo), \
echo $f; \
)
它不会列出上面的foo
创建的文件touch foo
,而是列出任务开始之前foo
文件是否已经存在,像这样:
$ make foo # first time call, file 'foo' doesn't exists yet
$ make foo # second time call, file 'foo' already exists
foo
在执行了以上所有命令之后,是否可以评估ls
?
答案 0 :(得分:1)
这就是Make的工作方式。解析Makefile并调用任何Makefile函数,然后然后评估一个或多个配方。
您是否有理由不仅仅使用shell循环?
foo:
touch foo
for f in *foo*; do \
echo "$$f"; \
done
请注意,需要如何将美元符号加倍以使其免受make
的评估,以及通常应如何将Shell变量加双引号,除非您特别要求Shell在以下位置执行空白标记和通配符扩展值。
另一方面,更“虚假”的方法是显式记录所有依赖项。
.PHONY: all
all: foo
printf '%s\n' $^
foo:
touch $@
现在all
依赖于foo
,因此,如果foo
不存在,则必须知道必须创建all
才能执行foo
配方,或相对于其自身的依赖关系已过时(当然,目前没有依赖关系)。
make
变量$^
引用当前目标的依赖项,$@
扩展到当前配方目标。 printf
shell脚本是一种更经济的方式,每行打印一件事而没有循环。