[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: best practice for serialization of dependencies of a target

From: Paul Smith
Subject: Re: best practice for serialization of dependencies of a target
Date: Sun, 26 Jun 2022 09:30:23 -0400
User-agent: Evolution 3.44.1 (by

On Sun, 2022-06-26 at 03:20 +0200, Bruno Haible wrote:
> target: $(DEPS1) $(DEPS2)
>       command1
> However, with -j, $(DEPS1) and $(DEPS2) are being made in parallel.
> If this is not desired, I can transform this rule to
> target: $(DEPS1)
>         test -z "$(DEPS2)" || $(MAKE) $(DEPS2)
>         command1
> or (equivalently?)
> target: $(DEPS1)
>         $(MAKE) target2
> target2: $(DEPS2)
>         command1
> .PHONY: target2
> The question is: Are these two rewrites really equivalent? If not,
> how do they differ, and what is the best practice?

I'm not sure either of these are equivalent, because they will not
build "target" if the $(DEPS1) prerequisites are older but the $(DEPS2)
prerequisites are newer than "target".

Say DEPS1 = one and DEPS2 = two, and the modification times are one <
target < two.

Now in your original, "target" will be rebuilt because "two" is newer
than it.  But in both of your replacements, "target" will not be built
because it doesn't list DEPS2 ("two") as a prerequisite.

And in fact, because "target" is not built make won't even try to build
DEPS2, so they won't get rebuilt at all unless some DEPS1 prerequisite
makes "target" out of date.

If we assume that this doesn't matter (maybe "target" is PHONY), then
the only obvious difference to me is that in the first option, it's
possible that the submake won't be run at all (if DEPS2 is empty) while
in the second option you will always run a sub-make.  If your makefiles
have side-effects merely by being invoked (such as rebuilding included
files or whatever) that could make a difference.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]