GNU-Make创建的automatic variables在某些情况下非常方便:
.SECONDEXPANSION:
%-processed.md: $$(wildcard $$*.m4) $(wildcard macros/*.m4) %.md
m4 $^ > $@
然而,当有人试图在makefile中的其他地方添加依赖时,这个偶然的世界会爆炸:
.PHONY: force
force: ;
mybook-processed.md: force
现在突然m4
抱怨说“force”不是有效的输入文件。这当然不是,但它出现在$^
变量中,因为它已附加到先决条件列表中。
有没有办法只访问直接配方定义中定义的先决条件而忽略其他配方?
答案 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,$$*) $< > $@
这种方式只使用更稳定的$<
自动变量,而另一个更可预测,但代码有些重复。