write:
@echo `date`
file_1: write file_2
@echo "file_1 begin"
$(shell sleep 3)
@echo "file_1 end"
file_3: write file_4
@echo "file_3 begin"
$(shell sleep 3)
@echo "file_3 end"
all: file_1 file_3
.PHONY: write
When I run make, it outputs:
Sat Oct 9 15:22:45 CST 2021
file_1 begin
file_3 begin
file_1 end
file_3 end
target write run only once.
My ultimate goal is to calculate the execution time of file_1 and file_3 by writing the start time of target write. In the process of testing whether it will be covered, the above problems were found. If there is a better way to calculate the time, let me know.
First, it's virtually always an error to use the
$(shell ...)function inside a recipe. A recipe is already running in the shell, so it's not needed, and it has unexpected behaviors. Why not just use@sleep 3here instead?There is no way to make a single target get built more than one time in a single invocation of make. That would be very bad: consider if you have multiple programs all depending on one
.ofile for example: would you want to recompile that.ofile many times?Anyway, this won't really do what you want:
This doesn't measure the execution time of
file_1because the start date is written, thenfile_2is built, thenfile_1is built. So you're including the execution time offile_2as well.And, of course, if you ever enable parallel builds all bets are off.
If you want to measure something, put the start/stop operations inside the recipe, not using prerequisites. You can hide it in a variable to make it less onerous to type.