如何实现一个隐式规则,该规则取决于GNU Make中一个类似命名的文件?

时间:2018-09-05 18:50:57

标签: makefile gnu-make

如果我想在用户运行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

这是怎么做的?

1 个答案:

答案 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包含您在命令行上提供的要创建的目标。