On 22.02.2013 03:31, Ian Lynagh wrote:
>
> Hi all,
>
> The attached Makefile causes an infinite loop with parallel make when
> using make 3.81 (on amd64/Linux):
>
> $ make setup
> touch B.hs A.hs
> sleep 2
> touch B.hi B.dyn_hi
> sleep 2
> touch B.o B.dyn_o
> sleep 2
> touch A.dyn_hi
> sleep 2
> touch A.o A.dyn_o
>
> $ make so
> true 1 B.hi B.o
> false 1
> make: *** [so] Error 1
>
> $ make so -j2
> true 1 B.hi B.o
> [doesn't terminate]
I was able to reproduce that behavior GNU Make version 3.81-r2 found in
Gentoo Linux.
When I turn the last call into
$ make so -j2 --debug
it keeps looping
" File `so' does not exist."
> I can't reproduce it with 3.82, but I don't know for sure whether it's
> fixed or whether it's just luck that it doesn't get tickled.
>
>
> However, even if it is fixed in 3.82, that doesn't really help me right
> now as I would really like my build system to work with the make that
> people have installed, and 3.81 is still very common.
I cannot reproduce it with 3.82, either.
> Is anyone able to explain what causes the bug, so that I can try to
> alter the build system to avoid it, please?
My understanding is that the trouble comes from rules that
* are not declared phony but still
* do not update the timestamps of their targets .
A solution could be to
a) Add a line
.PHONY: so A.dyn_o A.hi Aa.o B.hi A.hs
so that all deep dependencies of target "so" ..
so
A.dyn_o
A.hi
Aa.o
B.hi
A.hs
.. are marked phony or
b) add lines
<tab>touch $@
to all pattern rules and a new rule to update A.o
A.o:
<tab>touch $@
to make sure timestamps are updated as expected.
With either approach, the looping stops with 3.81-r2 for me. I do not
mean to say that the unmodified Makefile GNU make should loop, I am not
sure about that. However, the Makefile does have its part.
As a last resort (meaning if you cannot do changes like those mentioned
above to your Makefile for sonme reason), you could make the Makefile
require GNU make 3.82 or later:
minimum_version := 3.82
recent_enough := $(filter $(minimum_version),$(firstword \
$(sort $(MAKE_VERSION) $(minimum_version))))
ifeq ($(recent_enough),)
$(error GNU Make $(minimum_version) or later is minimum_versioned)
endif
That's an adapted version of an idea from
<http://www.jgc.org/blog/cookbook-sample.pdf>.
> Also, is there a way to tell make not to treat any file as intermediate?
> I think that it's possible that this would work around the problem.
> If that's not possible, then if I can make a list of all files that the
> build system might build then adding
> list of all files : | exists
> exists:
> touch $@
> would do it, right?
> Although then, if the build system didn't actually find a rule for a
> file in the list, then the dependency on exists would make it think
> that it could build it; is there any way to avoid that?
I do not understand that part, sorry. Please elaborate more.
Best,
Sebastian
_______________________________________________
Bug-make mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-make