Here is a simplified Makefile showing this bug:

cat >Makefile <<"EOF"
%.bar: %.c foo.h
        cat $^ >$@ || rm $@

foo.h: foo.h.in
        cat $^ >$@ || rm $@
EOF

cat >main.y <"EOF"
%%
command:
      "q"                     { return 1; }
      ;
%%
EOF

echo bar >foo.h.in



# Again 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: Aucun fichier ou dossier de ce type

# 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

-- 
Francois Gouget <[email protected]>              http://fgouget.free.fr/
               RFC 2549: ftp://ftp.isi.edu/in-notes/rfc2549.txt
                IP over Avian Carriers with Quality of Service



-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to