GNU make - 强制 PHONY 目标的依赖顺序

问题描述 投票:0回答:3

我有一个如下的 Makefile,我关心

up-clean
的依赖顺序:

.PHONY: up
up: down
    docker-compose up -d

.PHONY: up-clean
up-clean: down-clean up

.PHONY: down
down:
    docker-compose down

.PHONY: down-clean
down-clean:
    docker-compose down -v

显然重要的是,在

up-clean: down-clean up
中,
down-clean
必须
up
之前执行。对于普通的 make 目标,解决方案是添加一个条目
up: down-clean
,但由于这些是 PHONY 目标,这将使
up
在功能上等同于
up-clean
,每次都会删除卷。显然,这是不可接受的。

实际上,GNU make 尊重依赖关系的顺序,但它不保证这一点,因此并不完全值得信赖,或者说

-j
根本不值得信赖。在这种情况下,有什么方法(如果有的话)可以确保依赖项的执行顺序而不改变构建其他目标的结果?

编辑:尝试使用仅订单先决条件似乎不起作用,可能是因为与

.PHONY
的交互。添加

up: | down-clean

导致执行日志为:

$ make up
docker-compose down
<...>
docker-compose down -v
Removing volume <...>

这是正常先决条件应该发生的情况,而不是仅限订单的先决条件。

makefile gnu-make
3个回答
2
投票

最简单的答案是使用 make 的递归调用:

up-clean:
        $(MAKE) down-clean
        $(MAKE) up

1
投票

GNU make 4.4 开始,您可以使用

.WAIT
伪目标显式序列化您的先决条件,例如,

.PHONY: up-clean
up-clean: down-clean .WAIT up

在 4.4 之前,GNU Make 文档没有对启用并行执行的顺序或执行做出任何承诺。但是,任何符合 POSIX 标准的 make 实现(重点是我的) ...应将所有先决条件视为目标本身,并递归地确保它们是最新的,

按照它们在规则中出现的顺序
处理它们。 make 实用程序应使用文件的修改时间来确定相应的目标是否已过期。

当然,在并行模式下,GNU make 并不能完全符合这个要求。

但是,4.4版本还添加了

--shuffle

选项,并且从

该选项的实现者所做的研究

来看,很明显,非确定性的唯一来源是
-j选项和并行模式执行情况,补丁和测试的内容也证明了这一点,并由 GNU make 项目的其他成员进行了审查。
因此,在4.4之前的版本中,我们可以放心地假设,只要make以非并行模式执行,先决条件就会严格按照指定的顺序从左到右执行。在 4.4 之前的版本中,我们可以使用 
.NOTPARALLEL

伪目标禁用并行性,只需将其添加到您的文件中,例如,

.NOTPARALLEL: # ensures that all deps are executed strictly in order

.PHONY: up
up: down
    docker-compose up -d

.PHONY: up-clean
up-clean: down-clean up

.PHONY: down
down:
    docker-compose down

.PHONY: down-clean
down-clean:
    docker-compose down -v

另请注意,
--shuffle

尊重

.NOTPARALLEL目标的存在,这证实了我们的假设:顺序可能与语法顺序不同只是因为并行执行。
    

另一种选择是在

0
投票
上对

up

 进行建模,而不是将后者作为前者的先决条件:
.PHONY: up
up: down
    docker-compose up -d

.PHONY: up-clean
up-clean: down-clean
    docker-compose up -d

如果你想让它变得更干燥,你可以将
docker-compose
命令分解为变量:

UP_COMMAND = docker-compose up -d

.PHONY: up
up: down
    $(UP_COMMAND)

.PHONY: up-clean
up-clean: down-clean
    $(UP_COMMAND)


© www.soinside.com 2019 - 2024. All rights reserved.