"make: Nothing to be done for 'target'" 出现错误

4
让我用一个例子来说明。
mkdir test
cd test
touch target
make target

这将导致:make: Nothing to be done for 'target'. 所以,make告诉我没有任务需要执行。这是因为make没有找到制作target的规则,但由于target已经存在,make告诉我没有任务需要执行。
现在,我不想要这样。我希望make在找不到target的规则时给我一个错误,即使target已经存在。
我尝试了以下方法:
echo '.DEFAULT:
        echo make: *** No rule to make target `$@'.  Stop.
        false'> Makefile

但这并不会阻止在制作多个目标时进行make操作。
3个回答

8
问题在于,make 假定目标名称也是一个将由给定命令构建的文件。

但有时这并不是真实情况(例如,“clean”)。为了告诉 make 某些目标不会构建此文件,您需要使它们“虚假”。请将以下行放入您的 Makefile 中以达到此目的:

.PHONY: target

2
如果你仔细思考,你会发现这是一个先有鸡还是先有蛋的问题(或者说无限回归)。假设你制定了一条规则:“在创建目标之前必须有一条规则”,那么你就会得到一条规则,它说“目标依赖于X”(其中X是另一个文件)。这可以写成:target depends on X
target: X
        command to build target from X

但是,你又回到了起点:你也需要一条规则来创建X。那么怎么做呢?你可以有一条不依赖任何东西的规则,在需要时神奇地创建文件X

X:
        command to build X from nothing

没有这样的规则,你就会陷入无限循环。
因此,make 的设计是确保文件存在并且是最新的。如果文件存在,并且没有隐式或显式的规则来指定如何生成它,则该文件是最新的。你想要做的事情是不可能的。

好观点,但我正在应对另一个问题(在我的问题中没有清楚描述)。感谢回复。我将在创建一个简单的示例来说明问题后创建一个新问题。 - To1ne
实际上这里并没有先有鸡还是先有蛋的问题。你只需要预先声明所有的蛋(就像大多数编程语言中的变量声明一样),这非常不像制造过程,是的。 - bobbogo
下投票。使用虚假目标似乎可以实现原帖作者想要的效果。 - iheanyi

0

实际上,这听起来像一个完全合理的(虽然有些误导人)请求。不过,你必须显式地列出每个带有空配方规则的源文件。

给你:

Makefile: ;

.PHONY: dodgy
dodgy%: dodgy; $(error You must provide a rule for $*)
%: dodgy% ;

布丁的证明:
$ rm aa
$ make aa
Makefile:4: *** You must provide a rule for aa.  Stop.
$ touch aa
$ make aa
Makefile:4: *** You must provide a rule for aa.  Stop.

请注意,行Makefile: ;是必需的。毕竟,make尝试做的第一件事就是重建Makefile。
还要注意,万能模式规则是非终端的。这可能会对性能造成巨大影响。正如手册所说的关于匹配任何规则的内容:“它们非常有用,但是让make考虑它们可能需要很长时间。”

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接