bug-make
[Top][All Lists]
Advanced

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

Re: Circular dependency with order-only dependencies


From: Paul Smith
Subject: Re: Circular dependency with order-only dependencies
Date: Wed, 23 Jan 2019 13:55:49 -0500

On Wed, 2019-01-23 at 19:55 +0200, Eli Zaretskii wrote:
> > From: Paul Smith <address@hidden>
> > Date: Wed, 23 Jan 2019 12:00:20 -0500
> > 
> > GNU make's internal dependency graph determines the order in which
> > targets are built.  It must be acyclical, otherwise make can never
> > choose which target to build before others.
> > 
> > In your example makefile you have a cycle:
> > 
> >    b -> t -> a.o -> a.h -,
> >    ^_____________________/
> > 
> > So make can never correctly choose which target to build first,
> > without breaking the cycle.
> 
> It's only a cycle if neither a.h nor b exist.  But the same message
> is emitted if a.h does exist and is newer than foo, in which case
> there's no need to rebuild a.h, and thus no cycle.  And if a.h is
> outdated wrt foo, but b exists, then I'd expect Make to update a.h
> and then rebuild b, at which point there's also no cycle because a.h
> is up to date.

Well, you didn't say that the dependencies were partially created
already :).  Your example only used "touch foo" so I didn't realize you
were expecting one of a.h or b to already be present as well.

However I don't think that matters.

The state of foo is not relevant here: make must always check targets
and the circular dependency is detected while walking the graph, before
it decides whether or not anything is out of date.  Whether foo exists
or is newer than a.h doesn't make any difference.

Are you assuming that order-only prerequisites are only updated if
their target is out of date?  Maybe you are thinking that it works
something like, all the normal prerequisites are brought up to date,
then we check to see whether the target needs to be rebuilt, and only
if the target is out-of-date then we update all the order-only
prerequisites first then update the target.

That's not how it works.  Order-only prerequisites are considered
identically to normal prerequisites in every way except one: after all
the prerequisites, including order-only prerequisites, are brought up
to date following the standard algorithm and we're determining whether
the target is outdated, we skip order-only prerequisites.

In the case of your example, make considers "all", then considers "b",
then considers "t", then considers "a.o", then considers "a.h", then
considers "foo", then considers "b".  It doesn't matter what the result
of considering "foo" was: make still needs to see if "b" needs to be
brought up to date.  In order to see if "b" is out of date, it needs to
consider "t", etc. and you have a cycle.




reply via email to

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