GNU-Make的自动变量只能作为当前配方定义的范围吗?

时间:2017-02-15 07:54:54

标签: makefile gnu-make

GNU-Make创建的automatic variables在某些情况下非常方便:

.SECONDEXPANSION:

%-processed.md: $$(wildcard $$*.m4) $(wildcard macros/*.m4) %.md
    m4 $^ > $@

然而,当有人试图在makefile中的其他地方添加依赖时,这个偶然的世界会爆炸:

.PHONY: force
force: ;

mybook-processed.md: force

现在突然m4抱怨说“force”不是有效的输入文件。这当然不是,但它出现在$^变量中,因为它已附加到先决条件列表中。

有没有办法只访问直接配方定义中定义的先决条件而忽略其他配方?

3 个答案:

答案 0 :(得分:1)

不,不可能。这些信息甚至不在make的内部结构中。

您的示例解决方案不是我使用的解决方案。如果您的命令只接受某些类型的文件,我会使用filter来确保它只看到那些类型的文件:

.SECONDEXPANSION:

%-processed.md: $$(wildcard $$*.m4) $(wildcard macros/*.m4) %.md
        m4 $(filter %.m4 %.md,$^) > $@

答案 1 :(得分:1)

您可以为force这样的伪目标采用命名约定,比如说MAGIC/force。然后$(filter-out MAGIC/%,$^) - 仍然有点重复,但不是那么糟糕。

答案 2 :(得分:0)

到目前为止,我发现这样做的唯一方法是停止使用自动变量并自行构建。我真的希望有人能给出更好的答案,但这是我目前的解决方案:

.SECONDEXPANSION:

process_prereqs = $(wildcard $1.m4) $(wildcarad macros/*.m4)
%-processed.md: %.md $$(call process_prereqs,$$*)
    m4 $(call process_prereqs,$$*) $< > $@

这种方式只使用更稳定的$<自动变量,而另一个更可预测,但代码有些重复。