按文件中的顺序覆盖 Makefile 中的目标是否合法?

Is it legal to override target in Makefile by order in a file?

我有一个 Makefile:

.PHONY: all
all: target1

target1:
    $(info "target1")

target1:
    $(info "target1 override")

如果从 bash 执行 "make" 它将响应:

$ make
Makefile:8: warning: overriding recipe for target 'target1'
Makefile:5: warning: ignoring old recipe for target 'target1'
"target1 override"
make: Nothing to be done for 'all'.

这种行为是我预料之中的,因为我希望目标的最新定义将被 Makefile 的解析器采用。

如果规则被覆盖,期望 Makefile 中的最新规则将被采用是否合法?

是否可以消除警告?

P.S。我还尝试了另一个 Whosebug 问题的答案,例如使用 "override" 关键字和“::”符号。它没有帮助(出现错误和来自 Makefile 的相同警告)。

Is it legal to expect that the latest rule from the Makefile will be taken if the rule is overridden?

包含为同一目标提供配方的多个目标规则的 makefile 违反了 the POSIX specifications for make:

Only one target rule for any given target can contain commands.

违反这一规定不会让警察对你下手,但它可能理所当然地平息必须使用你的代码的其他开发人员和管理人员的愤怒,无论是现在还是以后。 make 的实现在出现包含此类多个配方的 makefile 时,不受规范的任何特定行为的约束。

您提供的诊断消息和您描述的行为具有 GNU make 的特征。如果您愿意依赖特定的 make 实现,那么依赖 section 4.11 of its manual 是合理的,它表示:

There can only be one recipe to be executed for a file. If more than one rule gives a recipe for the same file, make uses the last one given and prints an error message.*

(脚注是我的。)但是依赖它会使您的 makefile 不可移植。其他 make 实现可能会拒绝 makefile,选择第一个配方,选择一个随机配方,按某种顺序选择所有匹配的配方,或者表现出任何明显或不明显的破坏方式。提醒您这一点是该消息的目的。

Is it possible to get rid of warnings?

继续假定 GNU make,手册明确表示将发出诊断,并且 its summary of command-line options 没有描述任何我希望在不抑制有问题的输出的情况下抑制输出实际构建。

底线

这个问题给人的印象是您认为所描述的用法应该是可以接受的,因此诊断只是一个麻烦。不是这种情况。这样的用法至少是一种糟糕的风格,它会给你自己和他人带来真正的问题。无论您试图以这种方式完成什么,都有更好的选择。


*指的是目标规则。匹配目标的后缀和模式规则是另一回事。