bash 读取 makefile 中的文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/13614275/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading a file inside makefile
提问by hari
I want to read a file called metafileinside a makefile.
我想在 makefile 中读取一个名为metafile的文件。
metafile looks something like this: 
file1 
file2 
file3 
元文件看起来像这样:
file1 
file2 
file3
I need to read this metafile inside my makefile line by line and check if the files mentioned inside exists or not and only print names of files which exists.
我需要在我的 makefile 中逐行读取这个元文件,并检查里面提到的文件是否存在,并且只打印存在的文件的名称。
I've tried a few things without success. like:
我已经尝试了一些没有成功的事情。喜欢:
FILE=`cat metafile`
for line in $(FILE); if [ -e $${line} ]; then echo $${line} fi; done;
回答by tripleee
You can put an arbitrary piece of shell script in a target. Keeping the file's contents in a Makefile variable does not make any sense to me, unless you also need the data in other targets for other reasons. (If so, you cannot use backticks, anyway.)
您可以在目标中放置任意一段 shell 脚本。将文件的内容保存在 Makefile 变量中对我来说没有任何意义,除非出于其他原因您还需要其他目标中的数据。(如果是这样,无论如何你都不能使用反引号。)
target:
        @while read -r file; do \
            test -e "$$file" && echo "$$file"; \
        done <metafile
For what it's worth, the whileloop is a safer and more idiomatic way to loop over a file's lines in a shell script than the forloop with backticks, even though you see that a lot.
就其价值而言,与带反引号while的for循环相比,循环是在 shell 脚本中循环文件行的更安全、更惯用的方式,即使您经常看到这种情况。
The @prevents Make from echoing the shell script commands; take that out if for some reason you need to see them.  In fact, I recommend against using this, especially while you are debugging -- use make -sto have makerun silently once you are confident your recipe works correctly.
在@防止呼应shell脚本命令制作; 如果出于某种原因您需要查看它们,请将其取出。事实上,我不推荐使用这个,特别是当你在调试-使用make -s已经make默默运行,一旦你确信你的食谱正常工作。
A more idiomatic way to do this in a Makefile is to have a target depend on these files, and use Make's own logic:
在 Makefile 中执行此操作的一种更惯用的方法是让目标依赖于这些文件,并使用 Make 自己的逻辑:
target: file1 file2 file3
        @echo $(filter-out $?,$^)
This is GNU Make syntax; it might get more complex if you want to be portable to other Make flavors (to the point where maybe the shell script is preferable after all). It will echo everything on one line, but if you need separate lines, that should be a trivial fix.
这是 GNU Make 语法;如果您想移植到其他 Make 风格,它可能会变得更加复杂(毕竟 shell 脚本可能更可取)。它会在一行上回显所有内容,但如果您需要单独的行,那应该是一个微不足道的修复。
I would simply build a small auxiliary Makefile snippet and include the dependencies:
我会简单地构建一个小的辅助 Makefile 片段并包含依赖项:
target: target.d
target.d: metafile
        sed 's/^/target: /' $< >$@
include target.d
This builds a small list of dependencies so you don't need to list them in the target:dependencies explicitly; so instead of file1 file2 file3in the recipe above, the dependencies would live in the generated target.dwhich would contain
这会构建一个小的依赖项列表,因此您无需在target:依赖项中明确列出它们;因此,而不是file1 file2 file3在上面的配方中,依赖项将存在于生成的target.d包含
target: file1
target: file2
target: file3
You need to filter out the dependency on target.d(or leave it undeclared; I believe GNU Make should cope).
您需要过滤掉对的依赖target.d(或不对其进行声明;我相信 GNU Make 应该可以应对)。

