多个文件匹配中的'%'变量

时间:2014-03-06 10:15:03

标签: makefile

我想从几个来源制作一份完整的文本文档(因为其中一个文件源更改,我希望更改文档)。

我必须通过我开发的翻译传递它。我想通过语言作为论点,使其更清晰。

昨天深夜,我梦见了像这样的makefile ......

#makefile
# ...
my_complete_doc.%.html: my_trans_exe header.%.html $(wildcard source/*.%.html)
        $< --language $(variable_for_%) > $@

(?)它是否用所有拥有%个文件的语言替换header.language.html。一旦my_completed_doc.language.html之一被更改,文件source/*.language.html是否会更改?

(?)如何在几个先决条件中替换%,可能进入通配符并且必须在配方中?

1 个答案:

答案 0 :(得分:2)

首先,容易出问题:您希望在配方中使用'%'变量。答案是使用'$ *'自动变量:

my_complete_doc.%.html: my_trans_exe ...
    $< --language $* > $@

然后是一个简单的问题:是的,header.%.html先决条件是正确的。当您尝试构建my_complete_doc.dutch.html时,Make会将其评估为header.dutch.html,当您尝试构建my_complete_doc.french.html时,Make会将其评估为header.french.html

现在棘手的问题:先决条件$(wildcard source/*.%.html)。通常,Make会在执行任何规则之前展开$(wildcard ...)语句,或者决定要构建哪些目标。因此它会搜索source/foo.%.htmlsource/bar.%.html等任何文件(即是,名称包含字符'%'的文件,找不到,并将该语句计算为空字符串。但是如果你使用SECONDEXPANSION

,Make会推迟评估,直到它选择了规则
.SECONDEXPANSION:
my_complete_doc.%.html: my_trans_exe header.%.html $$(wildcard source/*.%.html)
    $< --language $* > $@

(注意'$$'。在第一个 - 普通 - 扩展,Make减少“$$(...)”到“$(...)”,在第二个 - 当' %'有一个值 - 它会扩展“$(...)”。)现在,如果您修改任何文件,例如source/foo.german.html,Make会认为文件my_complete_doc.german.html已过期且需要重建。