对目标的先决条件施加顺序

Impose an order for the prerequisites of a target

我有一个 makefile 片段:

all: $(objects)
fresh: clean all
clean: ;rm $(objects)

在这里,我想确保当我做 make fresh - clean 应该在 all.

之前

但是我怎么能确定这一点,因为当我做 make all 时,不应该做 clean


我可以想象一种方式可能是这样的

fresh: clean
    make all

这是解决这个问题的正确(或唯一)方法吗?

正如您在问题中已经建议的那样,在先决条件为 clean:

# At the very beginning of the makefile
CURRENT_MAKEFILE :=  $(lastword $(MAKEFILE_LIST))
# ...

.PHONY: fresh
fresh: clean
    $(MAKE) -f $(CURRENT_MAKEFILE) all

这是一个顺序,因为目标fresh依赖于先决条件cleanclean的配方将在fresh的配方之前执行,这反过来将执行all的配方。

请注意,我在这里使用 $(MAKE) instead of make 进行递归。

如果你使用 GNU make:

all:
    @echo $@
    @sleep 1
    @echo end $@

clean:
    @echo $@
    @sleep 1
    @echo end $@

fresh:: clean
fresh:: all

.PHONY: clean fresh all

请注意targets后的双冒号fresh!见 documentation:

The double-colon rules for a target are executed in the order they appear in the makefile.

如果你 运行 make -j2 fresh 它表明它按预期工作:

clean
end clean
all
end all

但是 fresh:: clean all 不能正常并行工作(可能是意外的)。

使用 BSD 制作:

 all:
    @echo $@
    @sleep 1
    @echo end $@

clean:
    @echo $@
    @sleep 1
    @echo end $@

fresh:  clean all
    @echo $@

.ORDER: clean all
.PHONY: clean all fresh

请注意以 .ORDER 开头的行。它也适用于并行化(参见 man make)。在没有并行化的情况下,行 fresh: 中的依赖项顺序很重要。