bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Make 3.81 May Incorrectly Regard Object Dependencies as Complete


From: Grant Erickson
Subject: Make 3.81 May Incorrectly Regard Object Dependencies as Complete
Date: Mon, 18 Feb 2008 22:12:42 -0800
User-agent: Microsoft-Entourage/11.4.0.080122

I have been establishing a build environment and infrastructure for a
project I am working on.

In the course of doing so, I have found some inexplicable behavior in make
3.81 when compiling and generating archive libraries in a pristine build
tree. The issue manifests itself on both Mac OS X / Darwin on i686 and
Ubuntu Desktop 7.10 on i686.

The behavior is that make creates the necessary object, depend and results
directories based on order-only prerequisites in my implicit rules,
correctly compiles the first source file into an object for the archive
library, but then regards all other objects as complete and then tries to
archive the library with non-existent and un-built objects:

    % make all
    mkdir -p .results/Makefile/foo/gnu/gcc/4/development
    mkdir -p .depend/Makefile/foo/gnu/gcc/4/development
    mkdir -p .build/Makefile/foo/gnu/gcc/4/development
    /usr/bin/gcc -DLIBS=1 -DALPHABET -Iinclude -Iinclude/alphabet -I./ -MT
    .build/Makefile/foo/gnu/gcc/4/development/a.o -MD -MP -MF
    ".depend/Makefile/foo/gnu/gcc/4/development/a.d" -O1 -g  -Werror -Wall
    -Wshadow -Wreturn-type -Wpointer-arith -Wunused-variable
    -Wmissing-prototypes -Wstrict-prototypes -c -o
    .build/Makefile/foo/gnu/gcc/4/development/a.o  a.c
    /usr/bin/ar -c -r
    .results/Makefile/foo/gnu/gcc/4/development/libalphabet.a
    .build/Makefile/foo/gnu/gcc/4/development/a.o
    .build/Makefile/foo/gnu/gcc/4/development/b.o
    .build/Makefile/foo/gnu/gcc/4/development/c.o
    .build/Makefile/foo/gnu/gcc/4/development/d.o
    .build/Makefile/foo/gnu/gcc/4/development/e.o
    .build/Makefile/foo/gnu/gcc/4/development/f.o
    .build/Makefile/foo/gnu/gcc/4/development/g.o
    .build/Makefile/foo/gnu/gcc/4/development/h.o
    /usr/bin/ar: .build/Makefile/foo/gnu/gcc/4/development/b.o: No such file
or directory
    make: *** [.results/Makefile/foo/gnu/gcc/4/development/libalphabet.a]
Error 1

If I then run make again, the order-only prerequisites having been already
satisfied this time around, things work as expected:

    /usr/bin/gcc -DLIBS=1 -DALPHABET -Iinclude -Iinclude/alphabet -I./ -MT
    .build/Makefile/foo/gnu/gcc/4/development/b.o -MD -MP -MF
    ".depend/Makefile/foo/gnu/gcc/4/development/b.d" -O1 -g  -Werror -Wall
    -Wshadow -Wreturn-type -Wpointer-arith -Wunused-variable
    -Wmissing-prototypes -Wstrict-prototypes -c -o
    .build/Makefile/foo/gnu/gcc/4/development/b.o  b.c
    [ ... ]
    /usr/bin/gcc -DLIBS=1 -DALPHABET -Iinclude -Iinclude/alphabet -I./ -MT
    .build/Makefile/foo/gnu/gcc/4/development/h.o -MD -MP -MF
    ".depend/Makefile/foo/gnu/gcc/4/development/h.d" -O1 -g  -Werror -Wall
    -Wshadow -Wreturn-type -Wpointer-arith -Wunused-variable
    -Wmissing-prototypes -Wstrict-prototypes -c -o
    .build/Makefile/foo/gnu/gcc/4/development/h.o  h.c
    /usr/bin/ar -c -r
    .results/Makefile/foo/gnu/gcc/4/development/libalphabet.a
    .build/Makefile/foo/gnu/gcc/4/development/a.o
    .build/Makefile/foo/gnu/gcc/4/development/b.o
    .build/Makefile/foo/gnu/gcc/4/development/c.o
    .build/Makefile/foo/gnu/gcc/4/development/d.o
    .build/Makefile/foo/gnu/gcc/4/development/e.o
    .build/Makefile/foo/gnu/gcc/4/development/f.o
    .build/Makefile/foo/gnu/gcc/4/development/g.o
    .build/Makefile/foo/gnu/gcc/4/development/h.o
    /usr/bin/ranlib
    .results/Makefile/foo/gnu/gcc/4/development/libalphabet.a

The debug output from make with '--debug="basic,implicit"':

GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i486-pc-linux-gnu
Reading makefiles...
Updating goal targets....
 File `all' does not exist.
   File `local-all' does not exist.
     File `alphabet' does not exist.
       File `.results/Makefile/foo/gnu/gcc/4/development/libalphabet.a' does
not exist.
         File `.results/Makefile/foo/gnu/gcc/4/development' does not exist.
        Must remake target `.results/Makefile/foo/gnu/gcc/4/development'.
Creating ".results/Makefile/foo/gnu/gcc/4/development"
        Successfully remade target file
`.results/Makefile/foo/gnu/gcc/4/development'.
         File `.build/Makefile/foo/gnu/gcc/4/development/a.o' does not
exist.
         Looking for an implicit rule for
`.build/Makefile/foo/gnu/gcc/4/development/a.o'.
         Trying pattern rule with stem `a'.
         Trying implicit prerequisite `a.c'.
         Trying rule prerequisite
`.depend/Makefile/foo/gnu/gcc/4/development'.
         Trying rule prerequisite
`.build/Makefile/foo/gnu/gcc/4/development'.
         Found an implicit rule for
`.build/Makefile/foo/gnu/gcc/4/development/a.o'.
           Looking for an implicit rule for `a.c'.
           No implicit rule found for `a.c'.
           File `.depend/Makefile/foo/gnu/gcc/4/development' does not exist.
          Must remake target `.depend/Makefile/foo/gnu/gcc/4/development'.
Creating ".depend/Makefile/foo/gnu/gcc/4/development"
          Successfully remade target file
`.depend/Makefile/foo/gnu/gcc/4/development'.
           File `.build/Makefile/foo/gnu/gcc/4/development' does not exist.
          Must remake target `.build/Makefile/foo/gnu/gcc/4/development'.
Creating ".build/Makefile/foo/gnu/gcc/4/development"
          Successfully remade target file
`.build/Makefile/foo/gnu/gcc/4/development'.
        Must remake target `.build/Makefile/foo/gnu/gcc/4/development/a.o'.
Compiling (gcc gnu/gcc/4) "a.c"
        Successfully remade target file
`.build/Makefile/foo/gnu/gcc/4/development/a.o'.
         File `.build/Makefile/foo/gnu/gcc/4/development/b.o' does not
exist.
         Looking for an implicit rule for
`.build/Makefile/foo/gnu/gcc/4/development/b.o'.
         Trying pattern rule with stem `b'.
         Trying implicit prerequisite `b.c'.
         Trying rule prerequisite
`.depend/Makefile/foo/gnu/gcc/4/development/'.
         Trying pattern rule with stem `b'.
         Trying implicit prerequisite `b.cpp'.
         Trying pattern rule with stem `b'.
         Trying implicit prerequisite `b.c'.
         Trying rule prerequisite
`.depend/Makefile/foo/gnu/gcc/4/development/'.
         Looking for a rule with intermediate file
`.depend/Makefile/foo/gnu/gcc/4/development/'.
          Avoiding implicit rule recursion.
         Trying pattern rule with stem `b'.
         Trying implicit prerequisite `b.cpp'.
         Looking for a rule with intermediate file `b.cpp'.
          Avoiding implicit rule recursion.
         No implicit rule found for
`.build/Makefile/foo/gnu/gcc/4/development/b.o'.
        Must remake target `.build/Makefile/foo/gnu/gcc/4/development/b.o'.
        Successfully remade target file
`.build/Makefile/foo/gnu/gcc/4/development/b.o'.
         File `.build/Makefile/foo/gnu/gcc/4/development/c.o' does not
exist.
         Looking for an implicit rule for
`.build/Makefile/foo/gnu/gcc/4/development/c.o'.
         Trying pattern rule with stem `c'.
         Trying implicit prerequisite `c.c'.
         Rejecting impossible rule prerequisite
`.depend/Makefile/foo/gnu/gcc/4/development/'.
         Trying pattern rule with stem `c'.
         Trying implicit prerequisite `c.cpp'.
         Trying pattern rule with stem `c'.
         Trying implicit prerequisite `c.cpp'.
         Looking for a rule with intermediate file `c.cpp'.
          Avoiding implicit rule recursion.
         No implicit rule found for
`.build/Makefile/foo/gnu/gcc/4/development/c.o'.
        Must remake target `.build/Makefile/foo/gnu/gcc/4/development/c.o'.
        Successfully remade target file
`.build/Makefile/foo/gnu/gcc/4/development/c.o'.

[ ... ]

         File `.build/Makefile/foo/gnu/gcc/4/development/h.o' does not
exist.
         Looking for an implicit rule for
`.build/Makefile/foo/gnu/gcc/4/development/h.o'.
         Trying pattern rule with stem `h'.
         Trying implicit prerequisite `h.c'.
         Rejecting impossible rule prerequisite
`.depend/Makefile/foo/gnu/gcc/4/development/'.
         Trying pattern rule with stem `h'.
         Trying implicit prerequisite `h.cpp'.
         Trying pattern rule with stem `h'.
         Trying implicit prerequisite `h.cpp'.
         Looking for a rule with intermediate file `h.cpp'.
          Avoiding implicit rule recursion.
         No implicit rule found for
`.build/Makefile/foo/gnu/gcc/4/development/h.o'.
        Must remake target `.build/Makefile/foo/gnu/gcc/4/development/h.o'.
        Successfully remade target file
`.build/Makefile/foo/gnu/gcc/4/development/h.o'.
      Must remake target
`.results/Makefile/foo/gnu/gcc/4/development/libalphabet.a'.
Archiving (ar gnu/gcc/4) "libalphabet.a"
/usr/bin/ar: .build/Makefile/foo/gnu/gcc/4/development/b.o: No such file or
directory
make: *** [.results/Makefile/foo/gnu/gcc/4/development/libalphabet.a] Error
1

If I run 'make -p', I see the expect dependencies for the library:

    .results/Makefile/foo/gnu/gcc/4/development/libalphabet.a:
    .build/Makefile/foo/gnu/gcc/4/development/a.o
    .build/Makefile/foo/gnu/gcc/4/development/b.o
    .build/Makefile/foo/gnu/gcc/4/development/c.o
    .build/Makefile/foo/gnu/gcc/4/development/d.o
    .build/Makefile/foo/gnu/gcc/4/development/e.o
    .build/Makefile/foo/gnu/gcc/4/development/f.o
    .build/Makefile/foo/gnu/gcc/4/development/g.o
    .build/Makefile/foo/gnu/gcc/4/development/h.o |
    .results/Makefile/foo/gnu/gcc/4/development

the expected results for 'a.o':

    .build/Makefile/foo/gnu/gcc/4/development/a.o: a.c |
    .depend/Makefile/foo/gnu/gcc/4/development
    .build/Makefile/foo/gnu/gcc/4/development
    #  Implicit rule search has been done.
    #  Implicit/static pattern stem: `a'
    #  Also makes: .build/Makefile/foo/gnu/gcc/4/development/a.so
    #  Last modified 2008-02-15 12:42:34
    #  File has been updated.
    #  Successfully updated.

However, for 'b.o', 'c.o', etc. the implicit rule inexplicably is
skipped/dropped:

    # Not a target:
    .build/Makefile/foo/gnu/gcc/4/development/b.o:

    # Not a target:
    .build/Makefile/foo/gnu/gcc/4/development/c.o:

The make environment is completely stand alone, that is MAKEFLAGS are set to
'-r -R'.

The implicit rules:

    $(ObjectDirectory)%$(SharedObjectSuffix)
    $(ObjectDirectory)%$(StaticObjectSuffix): %.c | $(DependDirectory)
    $(ObjectDirectory)
        $(preprocess-compile-and-assemble-c-or-c++)

    $(ObjectDirectory)%$(SharedObjectSuffix)
    $(ObjectDirectory)%$(StaticObjectSuffix): %.cpp | $(DependDirectory)
    $(ObjectDirectory)
        $(preprocess-compile-and-assemble-c++)

The commands:

    define tool-preprocess-compile-and-assemble-c
    $(CC) $(CPPFLAGS) $(CCFLAGS) $(CCNoLinkFlag) $(CCOutputFlag) $@
    $(CCInputFlag) $<
    endef

    define tool-preprocess-compile-and-assemble-c++
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(CXXNoLinkFlag) $(CXXOutputFlag) $@
    $(CXXInputFlag) $<
    endef

    $(DependDirectory) $(ObjectDirectory) $(ResultDirectory):
        $(create-directory)

The directory under question:

    a.c
    b.c
    bye.c
    c.c
    d.c
    e.c
    f.c
    g.c
    goodbye.cpp
    h.c
    hello.c
    hi.c
    include/
        alphabet/
        alphabet.h
        bye.h
        goodbye/
        goodbye.h
        hello/
        hello.h
        hi.h
        salutations/
    Makefile

The make file instructs the generation of three shared libraries:

    hello goodbye salutations

and one archive library:

    alphabet

I think I've chased down every common make mistake I can think of, including
empty rules, duplicate rules, environment variables, undefined variables,
etc.

Sample archive/directory under test available on request.

Regards,

Grant Erickson






reply via email to

[Prev in Thread] Current Thread [Next in Thread]