我想在makefile中读取一个名为 metafile 的文件。
元文件看起来像这样:
file1
file2
file3
我需要逐行读取makefile中的这个元文件,检查里面提到的文件是否存在,只打印存在的文件名。
我尝试了一些没有成功的事情。像:
FILE=`cat metafile`
for line in $(FILE); if [ -e $${line} ]; then echo $${line} fi; done;
答案 0 :(得分:14)
您可以在目标中放置任意一块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片段并包含依赖项:
target: target.d
target.d: metafile
sed 's/^/target: /' $< >$@
include target.d
这会构建一个小的依赖项列表,因此您无需在target:
依赖项中明确列出它们;因此,在上面的配方中,不依赖于file1 file2 file3
,依赖关系将存在于生成的target.d
中,其中包含
target: file1
target: file2
target: file3
你需要过滤掉对target.d
的依赖(或者保持未声明;我相信GNU Make应该应对)。