help-make
[Top][All Lists]
Advanced

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

Re: multiple prerequisites in pattern rules


From: Greg Chicares
Subject: Re: multiple prerequisites in pattern rules
Date: Thu, 29 Jan 2004 11:15:27 -0500

Rolf Sandau wrote:
> 
> Following "Recursive Make Considered Harmful"  Peter Miller and Paul D.
> Smith, "Advanced Auto-Dependency Generation" I created a Makefile that
> generates the dependencies of c-sources (%.P) when compiling the c-source.
> While avoiding re-exec of make, if dependency file does not exist and
> avoiding 'no rule to make target ...' if a prerequisite is removed there is
> still a problem left.
> If anyone kills just dependency-files, make wouldn't do anything, but I
> would prefer make to recompile and regenerate dependencies.

The dependency files contain state information from previous invocations
of make, so, as you point out, erasing them causes a problem that is not
automatically diagnosed. In that sense, the process is fragile: you can
delete .o files at will, but .P files must not be deleted.

It's not sufficient to say "just don't delete .P files" because the same
problem can arise even if you never do that. I often get signal 11 errors
  http://www.bitwizard.nl/sig11/
when making a large project. With a definition like
  MAKEDEPEND = $(CPP) ... | $(SED) ... > $*.P
a signal 11 in $(CPP) can result in a zero-byte .P file.

> For I couldn't
> find anything that helps, in my typical naive way I just tried a second
> prerequisite-pattern :
>       %.o: %.c %.P
> ... and what a surprise, it worked with my cygwin's gnu-make 3.80 :-)

With that rule, doesn't the .P file need to exist already?

# begin GNUmakefile
.SUFFIXES:

CC = gcc

objects = foo.o

.PHONY: all
all: $(objects)

MAKEDEPEND = $(CC) -M -o $*.P $<

%.o: %.c %.P
        $(MAKEDEPEND)
        $(CC) -c $< -o $@

-include $(objects:%.o=%.P)
# end GNUmakefile

If the .P file doesn't exist, make fails:

  C:/tmp[0]$ls foo*
  foo.c  foo.h
  C:/tmp[0]$make
  C:/tmp[2]$ls foo*
  foo.c  foo.h

The output of make -d [edited] reveals the reason:
 Must remake target `foo.P'.
 Failed to remake target file `foo.P'.
[...]
  Considering target file `foo.o'.
   File `foo.o' does not exist.
    Considering target file `foo.P'.
    Recently tried and failed to update file `foo.P'.
   Finished prerequisites of target file `foo.o'.
  Giving up on target file `foo.o'.

If it does exist, make does the right thing:

  C:/tmp[0]$touch foo.P
  C:/tmp[0]$make
  gcc -M -o foo.P foo.c
  gcc -c foo.c -o foo.o
  C:/tmp[0]$ls foo*
  foo.P  foo.c  foo.h  foo.o
  C:/tmp[0]$sed 10q foo.P
  foo.o: foo.c foo.h

If I add this rule
%.P:
        touch $@
then everything seems to work:

  C:/tmp[0]$make
  touch foo.P
  gcc -M -o foo.P foo.c
  gcc -c foo.c -o foo.o

> Now the questions:
> Is this a legal construction and should it work with other gnu-makes on
> other platforms too?

The grammar should be the same on every platform, because the same
source code is used.

> Sample:
> 
> ${OBJDIR}/%.o: %.c ${OBJDIR}/%.P
>       ${MAKEDEPEND};\
>       cp ${basename address@hidden ${basename address@hidden; \
[...]

It might be easier this way:
  http://make.paulandlesley.org/multi-arch.html

> Following "Recursive Make Considered Harmful"  Peter Miller

I've only read that paper a few times, but I think his thesis
is that harm occurs only when a recursive call to make uses
a submakefile that doesn't know the full DAG. That's not the
same thing as saying that recursive make per se is harmful,
which the title unfortunately seems to suggest.





reply via email to

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