Your message dated Sun, 21 Jun 2009 17:04:06 +0000
with message-id <[email protected]>
and subject line [bug #26864] make -j2 fails to rebuild intermediate file
has caused the Debian Bug report #530855,
regarding make -j2 fails to rebuild intermediate file
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
530855: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=530855
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: make
Version: 3.81-5
Severity: normal


I stumbled on a problem with make -j2. Here is how to reproduce the problem:

# First create some files:

cat >Makefile <<"EOF"
ALL=foo bar and much more

build-%/lib.so: build-%/rsrc.res build-%/main.o
        cat $^ >$@ || rm $@

# .SECONDARY: $(ALL:%=build-%/rsrc.res)
.SUFFIXES: .rc .res
.rc.res:
        cat $< >$@ || rm $@

$(ALL:%=build-%/rsrc.rc): rsrc.rc.in
        mkdir -p `dirname $...@`
        cat $< >$@ || rm $@

$(ALL:%=build-%/main.o): main.c
        mkdir -p `dirname $...@`
        cat $< >$@ || rm $@
EOF

echo foo >main.c
echo bar >rsrc.rc.in

# But note that the copy/paste may have messed up the tabs in the Makefile.


# Then do a normal build
make -j2 build-foo/lib.so
mkdir -p `dirname build-foo/rsrc.rc`
mkdir -p `dirname build-foo/main.o`
cat rsrc.rc.in >build-foo/rsrc.rc || rm build-foo/rsrc.rc
cat main.c >build-foo/main.o || rm build-foo/main.o
cat build-foo/rsrc.rc >build-foo/rsrc.res || rm build-foo/rsrc.res
cat build-foo/rsrc.res build-foo/main.o >build-foo/lib.so || rm build-foo/lib.so
rm build-foo/rsrc.res

# All good, now trigger a rebuild
touch main.c
make -j2 build-foo/lib.so
mkdir -p `dirname build-foo/main.o`
cat main.c >build-foo/main.o || rm build-foo/main.o
cat build-foo/rsrc.res build-foo/main.o >build-foo/lib.so || rm build-foo/lib.so
cat: build-foo/rsrc.res: Aucun fichier ou dossier de ce type

# -> make forgot to rebuild the build-foo/rsrc.res intermediate file!

# Let's try again
make -j2 build-foo/lib.so
cat build-foo/rsrc.rc >build-foo/rsrc.res || rm build-foo/rsrc.res
cat build-foo/rsrc.res build-foo/main.o >build-foo/lib.so || rm build-foo/lib.so
rm build-foo/rsrc.res

# -> Now that there was only the intermediate file to rebuild it worked fine.

# Let's try again without the -j2
touch main.c
make build-foo/lib.so
mkdir -p `dirname build-foo/main.o`
cat main.c >build-foo/main.o || rm build-foo/main.o
cat build-foo/rsrc.rc >build-foo/rsrc.res || rm build-foo/rsrc.res
cat build-foo/rsrc.res build-foo/main.o >build-foo/lib.so || rm build-foo/lib.so
rm build-foo/rsrc.res

# -> Works fine for non parallel builds


So there are two workarounds:
 * Disable parallel builds
 * Declare the rsrc.res intermediate file as .SECONDARY so that it's not 
necessary to rebuild it in the first place.


-- System Information:
Debian Release: squeeze/sid
  APT prefers testing
  APT policy: (500, 'testing'), (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 2.6.25.3fg1 (PREEMPT)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages make depends on:
ii  libc6                         2.9-4      GNU C Library: Shared libraries

make recommends no packages.

Versions of packages make suggests:
ii  make-doc                      3.81-4     Documentation for the GNU version 

-- no debconf information



--- End Message ---
--- Begin Message ---
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/



--- End Message ---

Reply via email to