我想在makefile中读取一个名为metafile的文件。
图元文件如下所示:
file1
file2
文件3
我需要逐行读取我的makefile中的这个元文件,并检查里面提到的文件是否存在,只打印存在的文件的名称。
我试过几次都没成功。类似:
FILE=`cat metafile`
for line in $(FILE); if [ -e $${line} ]; then echo $${line} fi; done;
您可以在目标中放入任意一段shell脚本。将文件的内容保存在Makefile变量中对我来说没有任何意义,除非您出于其他原因也需要其他目标中的数据。(如果是这样的话,你无论如何都不能使用反勾号。)
target:
@while read -r file; do
test -e "$$file" && echo "$$file";
done <metafile
值得一提的是,while
循环是在shell脚本中对文件行进行循环的一种更安全、更惯用的方式,而不是带有backticks的for
循环,尽管您经常看到这种情况。
@
防止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:
依赖项中显式列出它们;因此,依赖关系将存在于生成的包含的target.d
中,而不是上面配方中的file1 file2 file3
target: file1
target: file2
target: file3
您需要过滤掉对target.d
的依赖(或者不声明它;我认为GNUMake应该能够处理)。