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 _______________________________________________ Bug-make mailing list Bug-make@gnu.org http://lists.gnu.org/mailman/listinfo/bug-make