忽略仅订单先决条件
Ignore order-only prerequisites
我有一组目标,应该根据一些订单要求执行。有正确的顺序:
wake
fuse
flash
eep
verify
lock
其中一些目标被归类为另一个(虚假的)空目标:
.PHONY: wake
full: fuse flash eep lock
不幸的是,当我调用 make full --dry-run
时,我看到 make
试图以错误的顺序执行规则:wake flash eep lock fuse
。因此我得到不正确的结果(擦除 MCU)。
我已尝试添加一些仅订单先决条件。这是我的 Makefile 的骨架:
.PHONY: wake
wake:
<...>
.PHONY: flash
flash: build/main.hex | fuse
<...>
.PHONY: eep
eep: build/main.eep.hex | fuse flash
<...>
.PHONY: verify
verify: build/main.hex | fuse flash eep
<...>
.PHONY: fuse
fuse: | wake
<...>
.PHONY: lock
lock: | fuse flash eep
<...>
build/main.hex: <some files here>
<...>
现在 make full
工作正常,但即使我尝试执行某些特定规则,PHONY order-only 目标的规则也会执行。例如:
make eep
导致执行 wake fuse flash eep
。
我不想浪费时间完全刷机,而我只需要编写新的 eep 映像。
似乎所谓的“仅订单先决条件”被视为常规先决条件。
如何强制“仅订单先决条件”像真正的仅订单需求一样工作?有没有更优雅的方案?
我想你误解了 order-only 指的是什么。 Order only表示先决条件必须在target之前构建,但是如果order-only先决条件比target更新,则不需要重建target。但是,如果 order-only 先决条件不存在,目标仍然被认为是过时的(并且因为您所有的目标都是 .PHONY,其中 none 存在...)
您可以使用 'sentinel' 文件,而不是使用虚假目标,这些文件基本上是虚拟文件,标记 if/when 每个目标都是最后一个 运行:
.PHONY: flash fuse wake eep verify lock all
all: verify
flash: .flash.sentinel
fuse: .fuse.sentinel
wake: .wake.sentinel
eep: .eep.sentinel
.flash.sentinel: build/main.hex .fuse.sentinel
<...>
touch $@
.fuse.sentinel: .wake.sentinel
<...>
touch $@
.eep.sentinel: build/main.eep.hex fuse.sentinel flash.sentinel
<...>
touch $@
.wake.sentinel: build/main.eep.hex fuse.sentinel flash.sentinel
<...>
touch $@
verify: build/main.hex eep.sentinel fuse.sentinel flash.sentinel
<...>
注意,在干净的构建中,make all
将重建生成 .sentinel 文件的所有内容。对 make all
的后续调用只会重建任何被认为过时的内容。因此,例如,如果您修改了 build/main.hex
,它会重建 flash
、eep
、wake
和 fuse
,但如果您不进行任何更改,它不会做任何事情(因为一切都已经完成)。如果您构建 make flash
,它将重建闪存,以及它认为过时的任何其他先决条件。
现在,另一方面,如果您想在键入 make flash
时强制 仅 闪现规则 运行,无论是否有其他目标已过时,那么您可以添加一个对称树,一个有先决条件,一个没有:
.PHONY: flash fuse wake eep verify lock
.PHONY: do_flash do_fuse do_wake do_eep do_verify do_lock
.PHONY: all
all: do_lock
flash do_flash:
<...>
fuse do_fuse:
<...>
wake do_wake:
<...>
eep do_eep:
<...>
verify do_verify:
<...>
lock do_lock:
<...>
do_fuse : do_wake
do_flash : do_fuse
do_eep : do_flash
do_verify : do_eep
do_lock : do_verify
这意味着如果您执行 make flash
,它没有先决条件,并且只会 运行 规则。如果你做 make all
,all
有先决条件 do_verify
,它有另一个先决条件,等等,一直往下,所有这些都将是 运行 的正确顺序。
我有一组目标,应该根据一些订单要求执行。有正确的顺序:
wake
fuse
flash
eep
verify
lock
其中一些目标被归类为另一个(虚假的)空目标:
.PHONY: wake
full: fuse flash eep lock
不幸的是,当我调用 make full --dry-run
时,我看到 make
试图以错误的顺序执行规则:wake flash eep lock fuse
。因此我得到不正确的结果(擦除 MCU)。
我已尝试添加一些仅订单先决条件。这是我的 Makefile 的骨架:
.PHONY: wake
wake:
<...>
.PHONY: flash
flash: build/main.hex | fuse
<...>
.PHONY: eep
eep: build/main.eep.hex | fuse flash
<...>
.PHONY: verify
verify: build/main.hex | fuse flash eep
<...>
.PHONY: fuse
fuse: | wake
<...>
.PHONY: lock
lock: | fuse flash eep
<...>
build/main.hex: <some files here>
<...>
现在 make full
工作正常,但即使我尝试执行某些特定规则,PHONY order-only 目标的规则也会执行。例如:
make eep
导致执行 wake fuse flash eep
。
我不想浪费时间完全刷机,而我只需要编写新的 eep 映像。
似乎所谓的“仅订单先决条件”被视为常规先决条件。
如何强制“仅订单先决条件”像真正的仅订单需求一样工作?有没有更优雅的方案?
我想你误解了 order-only 指的是什么。 Order only表示先决条件必须在target之前构建,但是如果order-only先决条件比target更新,则不需要重建target。但是,如果 order-only 先决条件不存在,目标仍然被认为是过时的(并且因为您所有的目标都是 .PHONY,其中 none 存在...)
您可以使用 'sentinel' 文件,而不是使用虚假目标,这些文件基本上是虚拟文件,标记 if/when 每个目标都是最后一个 运行:
.PHONY: flash fuse wake eep verify lock all
all: verify
flash: .flash.sentinel
fuse: .fuse.sentinel
wake: .wake.sentinel
eep: .eep.sentinel
.flash.sentinel: build/main.hex .fuse.sentinel
<...>
touch $@
.fuse.sentinel: .wake.sentinel
<...>
touch $@
.eep.sentinel: build/main.eep.hex fuse.sentinel flash.sentinel
<...>
touch $@
.wake.sentinel: build/main.eep.hex fuse.sentinel flash.sentinel
<...>
touch $@
verify: build/main.hex eep.sentinel fuse.sentinel flash.sentinel
<...>
注意,在干净的构建中,make all
将重建生成 .sentinel 文件的所有内容。对 make all
的后续调用只会重建任何被认为过时的内容。因此,例如,如果您修改了 build/main.hex
,它会重建 flash
、eep
、wake
和 fuse
,但如果您不进行任何更改,它不会做任何事情(因为一切都已经完成)。如果您构建 make flash
,它将重建闪存,以及它认为过时的任何其他先决条件。
现在,另一方面,如果您想在键入 make flash
时强制 仅 闪现规则 运行,无论是否有其他目标已过时,那么您可以添加一个对称树,一个有先决条件,一个没有:
.PHONY: flash fuse wake eep verify lock
.PHONY: do_flash do_fuse do_wake do_eep do_verify do_lock
.PHONY: all
all: do_lock
flash do_flash:
<...>
fuse do_fuse:
<...>
wake do_wake:
<...>
eep do_eep:
<...>
verify do_verify:
<...>
lock do_lock:
<...>
do_fuse : do_wake
do_flash : do_fuse
do_eep : do_flash
do_verify : do_eep
do_lock : do_verify
这意味着如果您执行 make flash
,它没有先决条件,并且只会 运行 规则。如果你做 make all
,all
有先决条件 do_verify
,它有另一个先决条件,等等,一直往下,所有这些都将是 运行 的正确顺序。