Gcc lefts empty dependency files around if the preprocessor exits with an error. In some cases, when used in conjunction with gnu make, (and probably other tools), this can lead to inconsistent builds. The following shows a build succeeding where it should have failed, thus potentially resulting to an invalid executable (or whatever).
Consider the following legitimate (GNU) makefile: ------- Makefile --------- all: x.o x.d: # Generate dependency file gcc -E x.c -MP -MMD -MF x.d -MT x.o > /dev/null x.o: # and compile gcc -c x.c include x.d # Include dep file, to have it generated and used -------- end of Makefile --------- -------- x.c ------------- #include "myheader.h" -------- end of x.c ------------ -------- myheader.h (empty) ----------- -------- end of myheader.h ----------- Now run the following commands: $ make Makefile:8: x.d: No such file or directory # OK, expected (could have used -include to avoid the warning) gcc -E x.c -MP -MMD -MF x.d -MT x.o > /dev/null # Make builds x.d before including it gcc -c x.c # And compiles x.c without error $ rm myheader.h # just say the file was moved... $ rm x.d # someone suspected a problem with the dependencies $ make Makefile:8: x.d: No such file or directory # OK, expected as previously gcc -E x.c -MP -MMD -MF x.d -MT x.o > /dev/null x.c:1:22: error: myheader.h: No such file or directory # OK, expected make: *** [x.d] Error 1 # OK, gcc returned non-zero $ ls -l x.d -rw-r--r-- 1 steve steve 0 9 mai 18:19 x.d # BAD: Strange 0-sized file !! $ make make: Nothing to be done for `all'. # ERROR: should have failed !!! (because make included the empty x.d, and considered the previously generated x.o as up-to-date....) This can be illustrated by the following script, without using make, which I hope could easily be integrated as a unit test: ------- test.sh - exit 0 if working as expected ----- #! /bin/sh # setup files: x.c includes iexist.h rm x.* # cleanup echo "#include \"myheader.h\"" > x.c rm -f myheader.h # gcc must exit non-zero gcc -E x.c -MP -MMD -MF x.d -MT x.o > /dev/null if [ "$?" -eq "0" ]; then echo "failed(1): gcc should have exited non-zero" exit 1; fi # but x.d must not exist if test -f x.d; then ls -l x.d echo "failed(2): x.d should not exist"; exit 2 fi echo "test passed"; exit 0 # ok ---------- end of test.sh --------------------- Illustration: $ ./test.sh x.c:1:22: error: myheader.h: No such file or directory -rw-r--r-- 1 steve steve 0 9 mai 18:57 x.d failed(2): x.d should not exist ========== Additional notes ============ This is related to following bugs: #9517 (fixed) states that if the compiler fails, the .d file should not be deleted if the .o file is kept. (In that case the error was triggered by the compiler, not the preprocessor) #35697 (enhancement) asking for .d files to be created atomically. In the current case, we are just considering the preprocessor, which lefts incoherent files around, even if it is not interrupted. Solving #35697 will solve that bug, but the discussion is still open. I will also consider filing a bug on Gnu make after investigating a bit more its strange behaviour. Sincerely -- Summary: Empty dependencies left may cause invalid builds Product: gcc Version: 4.4.4 Status: UNCONFIRMED Severity: major Priority: P3 Component: driver AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: eric dot estievenart at free dot fr GCC build triplet: 4.4.4 (Debian 4.4.4-1) GCC host triplet: i686 debian GNU/Linux GCC target triplet: i486-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44049