Ok, my previous comment is not relevant (though it is still a bug in the
makefile anyway)...  But here is what is happening:

In the Makefile for src2, the default rule is ALL: $(lib) which means that
the default target depends on the $(lib) target which is defined as ../nat.a.
Since the Makefile in src1 already generated ../nat.a, that file is newly
created when Makefile in src2 is processed, and thus it is newer than the
source files x21.c and x22.c.  As such, the make process decides that nothing
needs to be done to create object files, which results in $? being empty (since
that variable contains only those dependencies that needed to be generated).

With your second version, you use an immediary target dummy, which forces the
evaluation of its dependencies since 'dummy' is not an actual file (thus it
does not have a timestamp that make can verify).

        Kris

On Mon, Jul 21, 2003 at 10:28:42AM -0600, Ferguson, Neale wrote:
> I have discovered something odd about make's behavior. I have the following
> test case:
>
> Nat
> |-Makefile
> +-/src1
>   |-Makefile
>   |-x11.c
>   |-x12.c
> +-/src2
>   |-Makefile
>   |-x21.c
>   |-x22.c
>
> The toplevel Makefile contains:
>
> all :
>         @echo "Process Nat/src1"
>         cd src1;$(MAKE) -$(MAKEFLAGS)
>         @echo "Process Nat/src2"
>         cd src2;$(MAKE) -$(MAKEFLAGS)
>
> The src1/Makefile:
>
> lib=../nat.a
>
> files = x11.c \
>         x12.c
>
> .c~.a: ;
> .c.a: ;
> .c~.o: ;
> .c.o: ;
>
> ALL : $(lib)
>
> $(lib) : $(lib)(x11.o) $(lib)(x12.o)
>         ar rv $(lib) $?
>         rm -f $?
>
> $(lib)(x11.o) : x11.o
> $(lib)(x12.o) : x12.o
>
> x11.o : x11.c
>         rm -f x11.o
>         $(CC) -c $(CFLAGS) x11.c
>
> x12.o : x12.c
>         rm -f x12.o
>         $(CC) -c $(CFLAGS) x12.c
>
> The src2/Makefile:
>
> lib=../nat.a
>
> files = x21.c \
>         x22.c
>
> .c~.a: ;
> .c.a: ;
> .c~.o: ;
> .c.o: ;
>
> ALL : $(lib)
>
> $(lib) : $(lib)(x21.o) $(lib)(x22.o)
>         ar rv $(lib) $?
>         rm -f $?
>
> $(lib)(x21.o) : x21.o
> $(lib)(x22.o) : x22.o
>
> x21.o : x21.c
>         rm -f x21.o
>         $(CC) -c $(CFLAGS) x21.c
>
> x22.o : x22.c
>         rm -f x22.o
>         $(CC) -c $(CFLAGS) x22.c
>
> (The x11.c files etc. contain int x11() { return 0; })
>
> If I run make from the top level I see:
>
> Process Nat/src1
> cd src1;make -
> make[1]: Entering directory `/FS/fs0300/usanefe/Nat/src1'
> rm -f x11.o
> cc -c  x11.c
> rm -f x12.o
> cc -c  x12.c
> ar rv ../nat.a x11.o x12.o
> a - x11.o
> a - x12.o
> rm -f x11.o x12.o
> make[1]: Leaving directory `/FS/fs0300/usanefe/Nat/src1'
> Process Nat/src2
> cd src2;make -
> make[1]: Entering directory `/FS/fs0300/usanefe/Nat/src2'
> ar rv ../nat.a
> rm -f
> make[1]: Leaving directory `/FS/fs0300/usanefe/Nat/src2'
>
> If I change the lower level makefiles to be:
>
> lib=../nat.a
>
> files = x11.c \
>         x12.c
>
> .c~.a: ;
> .c.a: ;
> .c~.o: ;
> .c.o: ;
>
> ALL : dummy
>
> dummy : $(lib)(x11.o) $(lib)(x12.o)
>         ar rv $(lib) $?
>         rm -f $?
>
> $(lib)(x11.o) : x11.o
> $(lib)(x12.o) : x12.o
>
> x11.o : x11.c
>         rm -f x11.o
>         $(CC) -c $(CFLAGS) x11.c
>
> x12.o : x12.c
>         rm -f x12.o
>         $(CC) -c $(CFLAGS) x12.c
>
> I then get:
>
> Process Nat/src1
> cd src1;make -
> make[1]: Entering directory `/FS/fs0300/usanefe/Nat/src1'
> rm -f x11.o
> cc -c  x11.c
> rm -f x12.o
> cc -c  x12.c
> ar rv ../nat.a x11.o x12.o
> a - x11.o
> a - x12.o
> rm -f x11.o x12.o
> make[1]: Leaving directory `/FS/fs0300/usanefe/Nat/src1'
> Process Nat/src2
> cd src2;make -
> make[1]: Entering directory `/FS/fs0300/usanefe/Nat/src2'
> rm -f x21.o
> cc -c  x21.c
> rm -f x22.o
> cc -c  x22.c
> ar rv ../nat.a x21.o x22.o
> a - x21.o
> a - x22.o
> rm -f x21.o x22.o
> make[1]: Leaving directory `/FS/fs0300/usanefe/Nat/src2'
>
> Apparently, other makes (i.e. non GNU make) do not exhibit this behavior
> (i.e. the 1st version of the makefile will produce the desired results).

--
Never underestimate a Mage with:
 - the Intelligence to cast Magic Missile,
 - the Constitution to survive the first hit, and
 - the Dexterity to run fast enough to avoid being hit a second time.

Reply via email to