Why the Makefile target is dependent on two targets, but only run once?

962 Views Asked by At
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.

1

There are 1 best solutions below

2
MadScientist On

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 3 here 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 .o file for example: would you want to recompile that .o file many times?

Anyway, this won't really do what you want:

file_1: write file_2

This doesn't measure the execution time of file_1 because the start date is written, then file_2 is built, then file_1 is built. So you're including the execution time of file_2 as 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.