如果我想在用户运行foo.txt
时创建make 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 $@
;见automatic variables的讨论。
第二,你的规则:
%: %.txt
不会做你认为它做的事情。与显式规则不同,创建没有配方的隐式或模式规则不会简单地为匹配模式的目标创建先决条件关系:而是deletes a pre-existing pattern rule。
由于您没有预先存在的模式规则,因此您的makefile与简单编写相同:
%.txt:
touch %.txt
并且没有办法用这个makefile构建目标clojure
。
一种解决方案是创建一个这样的虚拟配方:
% : %.txt
@:
%.txt:
touch $@
另一个解决方案,如果你没有其他目标想要添加到你的makefile中,那就是使用static pattern rule告诉make每个目标应该被认为是这种类型:
$(MAKECMDGOALS): % : %.txt
%.txt:
touch $@
MAKECMDGOALS
variable包含您在命令行上提供的任何目标。