【问题标题】:Reading a file inside makefile在makefile中读取文件
【发布时间】:2012-11-16 20:20:10
【问题描述】:

我想在 makefile 中读取一个名为 metafile 的文件。

元文件看起来像这样:
文件 1
文件2
文件3

我需要逐行读取我的makefile中的这个元文件,并检查里面提到的文件是否存在,并且只打印存在的文件的名称。

我尝试了一些事情但没有成功。喜欢:

FILE=`cat metafile`
for line in $(FILE); if [ -e $${line} ]; then echo $${line} fi; done;

【问题讨论】:

  • 您是否在食谱中尝试这两行?每一行都在一个单独的子shell中执行。您可以通过在末尾添加; \ 将一行与下一行连接起来。但是第一个变量将是$${LINE} 而不是$(LINE)

标签: bash shell makefile gnu


【解决方案1】:

您可以将任意一段 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 -smake 静默运行。

在 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 应该可以应付)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    相关资源
    最近更新 更多