URL: <http://savannah.gnu.org/bugs/?26864>
Summary: make -j2 fails to rebuild intermediate file Project: make Submitted by: srivasta Submitted on: Sun 21 Jun 2009 12:04:03 PM CDT Severity: 3 - Normal Item Group: Bug Status: None Privacy: Public Assigned to: None Open/Closed: Open Discussion Lock: Any Component Version: 3.81 Operating System: POSIX-Based Fixed Release: None _______________________________________________________ Details: This was reported by a Debian user. Here is how to reproduce the problem: cat >Makefile <<"EOF" # .bar files depend on .c files as well as foo.h %.bar: %.c foo.h cat $^ >$@ || rm $@ # foo.h is created from foo.in foo.h: foo.h.in cat $^ >$@ || rm $@ # main.c should be created from main.y below EOF cat >main.y <"EOF" %% command: "q" { return 1; } ; %% EOF echo bar >foo.h.in # The initial build is fine make -j2 main.bar cat foo.h.in >foo.h || rm foo.h yacc main.y mv -f y.tab.c main.c cat main.c foo.h >main.bar || rm main.bar rm main.c # But touch foo.h.in and things go wrong touch foo.h.in make -j2 main.bar cat foo.h.in >foo.h || rm foo.h cat main.c foo.h >main.bar || rm main.bar cat: main.c: No such file or directory # Here 'make -j2' decides to rebuild main.bar without first # recreating main.c although we explicitly stated that main.bar # depends on main.c. Here is what that command says with -d: Considering target file `main.bar'. Considering target file `main.y'. <--- Should be main.c File `main.y' was considered already. Considering target file `foo.h'. File `foo.h' was considered already. Pruning file `main.c'. <--- ??? Finished prerequisites of target file `main.bar'. Prerequisite `main.c' of target `main.bar' does not exist. <--- !!! Prerequisite `foo.h' is newer than target `main.bar'. Must remake target `main.bar'. cat main.c foo.h >main.bar || rm main.bar cat: main.c: No such file or directory <--- Doh! # The next attempt works though (but this time make does not # have to rebuild foo.h) make -j2 main.bar yacc main.y mv -f y.tab.c main.c cat main.c foo.h >main.bar || rm main.bar rm main.c # Compare this with 'make -j1' touch foo.h.in make -j1 main.bar cat foo.h.in >foo.h || rm foo.h yacc main.y mv -f y.tab.c main.c cat main.c foo.h >main.bar || rm main.bar rm main.c # Here make correctly realizes it must rebuild main.c before attempting # to run the command to generate main.bar. And the corresponding make # -d output: Prerequisite `foo.h.in' is newer than target `foo.h'. Must remake target `foo.h'. cat foo.h.in >foo.h || rm foo.h Successfully remade target file `foo.h'. Considering target file `main.c'. <--- Correct target File `main.c' does not exist. Pruning file `main.y'. Finished prerequisites of target file `main.c'. Must remake target `main.c'. <--- Yes! yacc main.y mv -f y.tab.c main.c Must remake target `main.bar'. cat main.c foo.h >main.bar || rm main.bar Successfully remade target file `main.bar'. Removing intermediate files... rm main.c It looks like make -j2 swapped main.c and main.y I can't get around the fact that there is a reproducible difference based on whether or not the -j2 argument was give, manoj _______________________________________________________ Reply to this item at: <http://savannah.gnu.org/bugs/?26864> _______________________________________________ Message sent via/by Savannah http://savannah.gnu.org/ _______________________________________________ Bug-make mailing list Bug-make@gnu.org http://lists.gnu.org/mailman/listinfo/bug-make