UNIX-WIZARDS Digest V12#071

Arthur W. Protin Jr. protin at pica.army.mil
Thu Apr 11 08:31:26 AEST 1991


Folks,
    Peter van Eijk <pve at cs.utwente.nl> described a problem with make
in a message on 08Apr91.  The "bug" involved a makefile modeled by

--makefile--
bar :: foo.k
	cp foo.k foo.c

bar :: foo.o
	cc -o bar foo.o

#if the following line is not commented out, the bug hides itself.
#bogus:  foo.c

And he did not think it was appropriate for make to give the results
  cp foo.k foo.c
  make: Fatal error: Don't know how to make target `foo.o'


Have I got sad news for you Peter.  (I am posting this because this
may interest others of you, and if I waited to see if someone else
posted anything better, I would never get back to it.)

[I saw the V7 sources for 'make' long ago and am commenting with what
little I remember.]

Peter expects the following
> What is the intended effect? Make first checks double colon rule #1, sees
> that bar does not exist (or is out of date of course w.r.t.  foo.k), calls
> the rule.  Then, and not earlier than that, make should check the dates of
> rule #2.  bar still doesn't exist, so foo.o should be created from foo.c
> (which exists by this time) using first the implicit .c.o rule, and then
> the second double colon rule.  make does not seem to be aware of the
> existence of foo.c, unless it appears in an unrelated place in the
> makefile!!!
This model would be appropriate if 'make' was a simple script interpreter.
However, 'make' is much more like a "load-and-go" compiler.  The set of
rules are parsed and assembled into a tree-like structure.  The sequence
of execution is not the sequence of the source but the sequence of the
tree walk with bunches of cashing.  The decision about which rules to
use is made before any of them are started.  The special case that provoked
me to look at the source was that the information about dependences was
largely ignored in the default rules.

foo.o:	../src/foo.c

will correctly determine if foo.o is out of date with regard to ../src/foo.c
but if it tries to make it, it will complain that it can't find foo.c
that is ./foo.c.

My suggestion for you is try an see if you can use the multiple target
rules.  Your example changes to:

foo.c :	foo.k
	cp foo.k foo.c

bar :	foo.o
        cc -o bar foo.o

but since foo.c is created/updated by a generator (and not cp) with several
other files, say for example, sna.c and garp.c.  Then the first rule would
look like:

foo.c \
sna.c \
garp.c \
 :	foo.k
	bas foo.k > foo.c 3> sna.c 4> garp.c


In summary, [ ... omitting 'make' bashing] to get the most out of make,
consider the makefile to be a relatively unordered description of
dependencies (with production rules) (only the first target name
is special).  When defaults fail, make the dependencies and productions
more explicit.  (There is a foo.c and it is dependent on foo.k and there
is a production to get from foo.k to foo.c.)


Arthur Protin <protin at pica.army.mil>
These are my personal views and do not reflect those of my boss
or this installation.



More information about the Comp.unix.wizards mailing list