On Wed, 2019-01-23 at 19:55 +0200, Eli Zaretskii wrote: > > From: Paul Smith <p...@mad-scientist.net> > > 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. _______________________________________________ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make