I have set of targets, that should be executed according to some order requirements. There is correct order:
wake
fuse
flash
eep
verify
lock
Some of those targets are grouped as another (phony) empty targets:
.PHONY: wake
full: fuse flash eep lock
Unfortunately, when i call make full --dry-run
i see that make
tries to execute rules in incorrect order: wake flash eep lock fuse
. Therefore i get incorrect results (erased-out MCU).
I've tried to add some order-only prerequisites. Here is skeleton of my Makefile with those:
.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>
<...>
Now make full
works fine, but PHONY order-only target's rules are executed even when i try to execute some specific rule. For example:
make eep
results in execution of wake fuse flash eep
.
I don't want to waste time for full flashing while i need only to write new eep image.
Seems like so-called "order-only prerequisites" are treated like regular prerequisites.
How can i force "order-only prerequisites" to work like real order-only requirements? Is there more elegant solution?
I think you misunderstand what order-only refers to. Order only means that a prerequisite must be built before the target, but if the order-only prerequisite is newer than the target, it does not require the target to be rebuilt. But, if the order-only prerequisite does not exist, the target is still considered out of date (and because all of your targets are .PHONY, none of these exist...)
Instead of using phony targets, you can use 'sentinel' files, which are basically dummy files that mark if/when each of the targets was last run:
Notice, that on a clean build,
make all
will rebuild everything generating the .sentinel files. Subsequent calls tomake all
will only rebuild anything that is considered out of date. So for example, if you modifiedbuild/main.hex
, it would rebuildflash
,eep
,wake
andfuse
, but if you don't change anything, it would not do anything (because everything is already done). If you buildmake flash
, it will rebuild flash, and any other prerequisites it considers out of date.Now, if, on the other hand you wanted to force only the flash rule to run when you type
make flash
, regardless of whether any of the other targets are out of date, then you could add a symmetrical tree, one that has prereq's and one that doesn't:Which means if you do
make flash
, it has no prerequisites, and will only run the rule. If you domake all
,all
has prerequisitedo_verify
, which has another prerequisite, etc, all the way down, and all of these would be run in the correct order.