您可以将任意一段 shell 脚本放入目标中。将文件的内容保存在 Makefile 变量中对我来说没有任何意义,除非您出于其他原因还需要其他目标中的数据。 (如果是这样,无论如何你不能使用反引号。)
target:
@while read -r file; do \
test -e "$$file" && echo "$$file"; \
done <metafile
不管怎样,while 循环是一种在 shell 脚本中循环文件行的更安全、更惯用的方法,而不是带有反引号的 for 循环 even though you see that a lot.
@ 阻止 Make 回显 shell 脚本命令;如果出于某种原因您需要查看它们,请将其取出。事实上,我建议不要使用它,尤其是在您调试时 - 一旦您确信您的配方正常工作,请使用 make -s 让 make 静默运行。
在 Makefile 中执行此操作的一种更惯用的方法是让目标依赖于这些文件,并使用 Make 自己的逻辑:
target: file1 file2 file3
@echo $(filter-out $?,$^)
这是 GNU Make 语法;如果您想移植到其他 Make 风格,它可能会变得更加复杂(毕竟可能 shell 脚本更可取)。它将在一行中回显所有内容,但如果您需要单独的行,那应该是一个简单的修复。
我会简单地构建一个小的辅助 Makefile sn-p 并包含依赖项:
target: target.d
target.d: metafile
sed 's/^/target: /' $< >$@
include target.d
这会构建一个小的依赖项列表,因此您无需在 target: 依赖项中明确列出它们;因此,依赖项将存在于生成的 target.d 中,而不是上面配方中的 file1 file2 file3
target: file1
target: file2
target: file3
您需要过滤掉对 target.d 的依赖(或者不声明它;我相信 GNU Make 应该可以应付)。