如果我想在用户运行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
。
这是怎么做的?
答案 0 :(得分:1)
这里有很多错误。首先,你的食谱是错误的;食谱中的%
并非特殊,因此不会被替换。无论模式匹配什么,您的命令touch %.txt
都会创建名为%.txt
的文件。您要在此处使用touch $@
;参见automatic variables的讨论。
第二,您的规则:
%: %.txt
不执行您认为的操作。与显式规则不同,创建没有配方的隐式或模式规则并不会简单地为与模式匹配的目标创建先决条件关系:而是deletes a pre-existing pattern rule。
由于您没有预先存在的模式规则,因此您的makefile与简单编写相同:
%.txt:
touch %.txt
并且无法使用此Makefile构建目标clojure
。
一种解决方案是创建一个虚拟配方,如下所示:
% : %.txt
@:
%.txt:
touch $@
如果您没有要添加到生成文件中的其他目标,另一种解决方案是使用static pattern rule告诉make,每个目标都应被视为这种类型:
$(MAKECMDGOALS): % : %.txt
%.txt:
touch $@
MAKECMDGOALS
variable包含您在命令行上提供的要创建的目标。