如何实现依赖于GNU Make中类似名称文件的隐式规则?



如果我想在用户运行时创建foo.txtmake foo,这很简单:

foo: foo.txt
foo.txt:
touch foo.txt

但是,如果我提前不知道名称foo,并且我想支持创建任何其他任意命名的文本文件,该怎么办?

这是我尝试过的:

%: %.txt
%.txt:
touch %.txt

但是如果我尝试make clojure,而不是运行touch clojure.txt,它会失败并No rule to make target clojure

这是怎么做到的?

这里有很多问题。 首先,你的食谱是错误的; 食谱中的%不是特别的,不会被替换。 您的命令touch %.txt创建字面上名为%.txt的文件,而不管模式匹配什么。 您想在此处使用touch $@;请参阅自动变量的讨论。

第二,你的规则:

%: %.txt

不做你想的那样。 与显式规则不同,创建没有配方的隐式或模式规则不会简单地为与模式匹配的目标创建先决条件关系:而是删除预先存在的模式规则。

由于您没有预先存在的模式规则,因此您的生成文件与简单地编写相同:

%.txt:
touch %.txt

并且无法使用此生成文件构建目标clojure

一种解决方案是创建一个这样的虚拟配方:

% : %.txt
@:
%.txt:
touch $@

如果您没有要添加到 makefile 中的其他目标,另一种解决方案是使用静态模式规则来告诉 make 每个目标都应被视为此类型:

$(MAKECMDGOALS): % : %.txt
%.txt:
touch $@

MAKECMDGOALS变量包含您在命令行上提供的任何目标。

最新更新