Hallo,

I have a makefile which works flawlessly when doing 'clean' and 'all', but which fails miserably when doing
'clean all'.

The reasons is pruning.
A clean subgoal deletes a generated C file (stack.c), which had been generated earlier on, at dependency inclusion time. When executing the all target, make eventually tries to build an object file for a library, assuming that the generated C file is still there.

The C compiler is then called upon a non existing source file, and fails:

 make clean all
gcc -c -o stack.o stack.c
gcc: stack.c: No such file or directory
gcc: no input files
make: *** [stack.o] Error 1

This is happening because when evaluating the prerequisites of the object file, make decides to prune the C source file.

Here are a simplified makefile, exhibiting the same behavior, and the output of a 'make -dr clean all'.

#
# Makefile model to exhibit make clean all failure
#
CCDEP = gcc -MM -MG -ansi

%.d: %.c
    @echo "== Dependencies C: $@"
    @$(CCDEP)  $(CFLAGS) $(I_PATH) $<   |  \
                   sed -e "s/$*\.o/$*.o $*.d /" \
                       -e "s/:/: Makefile /" > $@ ;     \
                       if [ ! -s $@ ]; then $(RM) $@ ; fi

%.o: %.c
    gcc -c -o $@ $<


# this is normally done by macro expansion for libraries, executables
# CORBA stubs generation etc. etc.
include stack.d

stack.c: stack.xml
    @echo "Simulating code generation"
    @cp stack.xml stack.c

stack: stack.o
    gcc  $(LD_FLAGS) -L/usr/lib  $< -o $@

.PHONY: all
all: stack

.PHONY: clean
clean:
    -...@rm stack.o stack stack.c stack.d


I must be overlooking something, possibly a better way to include the dependencies. I also think that this problem (or a related one) has possibly already posted on this list, but I could not find it

Does anyone know a solution to this?
You will probably have spotted another flaw in this: the dependencies (gcc --MM) are automatically generated and included even when only 'make clean' is called, on a directory which is clean already. Ideally I would like the 'include' directives to be called only as part of the 'all' target, but I understand this is conceptually not possible. Or is it?

We are using GNU make 3.81.

thanks in advance,

Michele
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 i686-redhat-linux-gnu
Reading makefiles...
Reading makefile `Makefile'...
Reading makefile `stack.d' (search path) (no ~ expansion)...
Updating makefiles....
 Considering target file `stack.d'.
  Looking for an implicit rule for `stack.d'.
  Trying pattern rule with stem `stack'.
  Trying implicit prerequisite `stack.c'.
  Found an implicit rule for `stack.d'.
   Considering target file `stack.c'.
     Considering target file `stack.xml'.
      Looking for an implicit rule for `stack.xml'.
      No implicit rule found for `stack.xml'.
      Finished prerequisites of target file `stack.xml'.
     No need to remake target `stack.xml'.
    Finished prerequisites of target file `stack.c'.
    Prerequisite `stack.xml' is older than target `stack.c'.
   No need to remake target `stack.c'.
   Considering target file `Makefile'.
    Looking for an implicit rule for `Makefile'.
    No implicit rule found for `Makefile'.
    Finished prerequisites of target file `Makefile'.
   No need to remake target `Makefile'.
   Pruning file `stack.c'.
   Considering target file `stack.h'.
    Looking for an implicit rule for `stack.h'.
    No implicit rule found for `stack.h'.
    Finished prerequisites of target file `stack.h'.
   No need to remake target `stack.h'.
  Finished prerequisites of target file `stack.d'.
  Prerequisite `stack.c' is older than target `stack.d'.
  Prerequisite `Makefile' is older than target `stack.d'.
  Prerequisite `stack.c' is older than target `stack.d'.
  Prerequisite `stack.h' is older than target `stack.d'.
 No need to remake target `stack.d'.
 Pruning file `Makefile'.
Updating goal targets....
Considering target file `clean'.
 File `clean' does not exist.
 Finished prerequisites of target file `clean'.
Must remake target `clean'.
Putting child 0x0912b3b0 (clean) PID 16948 on the chain.
Live child 0x0912b3b0 (clean) PID 16948 
Reaping winning child 0x0912b3b0 PID 16948 
Removing child 0x0912b3b0 PID 16948 from chain.
Successfully remade target file `clean'.
Considering target file `all'.
 File `all' does not exist.
  Considering target file `stack'.
   File `stack' does not exist.
    Considering target file `stack.o'.
     File `stack.o' does not exist.
     Looking for an implicit rule for `stack.o'.
     Trying pattern rule with stem `stack'.
     Trying implicit prerequisite `stack.c'.
     Found an implicit rule for `stack.o'.
      Pruning file `stack.c'.
      Pruning file `Makefile'.
      Pruning file `stack.c'.
      Pruning file `stack.h'.
     Finished prerequisites of target file `stack.o'.
    Must remake target `stack.o'.
gcc -c -o stack.o stack.c
Putting child 0x0912da90 (stack.o) PID 16949 on the chain.
Live child 0x0912da90 (stack.o) PID 16949 
gcc: stack.c: No such file or directory
gcc: no input files
Reaping losing child 0x0912da90 PID 16949 
make: *** [stack.o] Error 1
Removing child 0x0912da90 PID 16949 from chain.
_______________________________________________
Help-make mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/help-make

Reply via email to