[net.bugs] make dependency rules inadequate

essick (07/21/82)

#N:uiucdcs:8000001:000:1352
uiucdcs!essick    Jul 21 15:12:00 1982

	I had a segment of a makefile that looked like:

all:	a.o ....
a.o:	a.c		(not actually there, this is a default rule)
a.c:	a.h

the desired effect is for a.o to be regenerated when a.h is modified.
What happens is that nothing gets done.

	Examining the code for "make" yields a recursive procedure
that looks like:

	recurse on all dependent files
	if default rule says build, set flag
	if any of dependents show a more recent date, set flag
	if flag
	   follow the instructions to build this part

(the two if's that set the "flag" might be coded better than shown)

Anyway, in the above example, the a.c file never gets touched (rightly
so in my opinion).  My suggestion is that the determination of whether
to build the current thing should be expanaded to include
something to the effect of "if any of the dependencies were just built".

Note that "one of the dependencies was just built" does not mean that
the file was modified, the case in point being the one above.
Maybe the recursion should pass back a flag (it might but just ignores it)
that says "hey, something was done down here, so you need to do something
up there".  

I'd love to poke around with the source and see what I can do, but I 
don't have the time to fathom it all and then decide where the 
right places to modify are.

	Ray Essick	University of Illinois
	uiudcs!essick

thomas (07/22/82)

It is NOT the .c file which depends on the .h file.  The .o file depends
on the .h (i.e., when you change a .h file and recompile, nothing happens
to the .c file).  So, the rules should read:

all: a.o
a.o: a.c a.h

The only reason to have a .c depend on something is if the .c file is actually
generated from something else, e.g.:

a.c: a.y

=Spencer

johnl (07/22/82)

The problem stated is just wrong rules, not a make bug.  You said:

all:    a.o ...

a.c:    a.h

But a.c doesn't depend on a.h.  It's a.o that needs to be remade, not a.c,
so the right rules are:

all:    a.o ...

a.o:    a.c a.h

Unfortunately, make then has trouble figuring out how to remake a.o since
the default rule has been overridden, so you probably have to tell it.
Oh well.

	John Levine, decvax!cca!ima!johnl, harpo!esquire!ima!johnl

essick (07/23/82)

#R:uiucdcs:8000001:uiucdcs:8000002:000:837
uiucdcs!essick    Jul 23 11:02:00 1982

	Oh well, it appears that I was wrong and that if I had used my
head things would have been more obvious. I figured that since the
a.c file is where the `#include "a.h"` is, then a.c should be dependent
on a.h.  Boy was I wrong.  I had thought that the dependencies should
look like:

	all -> a.o -> a.c -> a.h

when in fact they should look like:

	all -> a.o +-> a.c
	           !
	           +-> a.h

Thanks for all the responses straightening me out.

Just for the book: the first dependency tree has the following fault:
Suppose that a.h is modified and, using my suggestion of passing 
modification status back up the tree, we decided to recompile a.c into
a.o.. Well, a.c still hasn't been touched, so the next time, things
will be recompiled because a.h has a more recent modification date than
a.c.

	Ray Essick
	uiucdcs!essick

thomas (07/24/82)

If you say
a.o: a.c a.h
in your makefile, but don't put any commands after it, make is perfectly
happy and uses the default .c.o rule.
=Spencer