From: throopw@sheol.UUCP (Wayne Throop)
Newsgroups: comp.lang.c
Subject: Re: 'make' woes (won't catch secondary dependancy)
Summary: what features are in God's make?
Date: 11 Oct 92 21:45:30 GMT

Actually, this discussion is drifting further and further away from
relevance to C as a language, but I'm not sure I know of a better
place to put it.  The groups that spring to mind, comp.programming
and comp.software-eng, both seem not to fit much better.  With that
meta-comment, on with discussing automated construction, and if
anybody knows a good newsgroup for this, let me know.

: From: hartman@ulogic.UUCP (Richard M. Hartman)
:: From: throop@aurs01.UUCP (Wayne Throop)
:: [...] to say that a .h file depends on another .h file
:: just because it includes it is incorrect.  There is nothing about
:: the including .h file that actually changes on account of
:: the included file changing.  Remember "x depends on y" means
:: "some process needs to read y and (potentially) update x".
:: With that agreed (I hope):
: Unfortunately I don't agree.  There are two ways to interpret
: the "depends" relationship.  The first, yours, means "file Y is
: created by some process operating on file X", this is a very
: specific, mechanistic interpretation.

More than two ways, of course.

: I prefer "the meaning of the contents of file Y depends upon 
: the (meaning of) the contents of file X"  This relies upon no
: external process, and accurately states the relationship of
: "depends on" as we use it, especially when it comes to include
: files that include other include files.  (Perhaps this practice
: was not as common when "make" was developed.....)

I agree that there are many things that can be meant by "depends"
when humans talk about it.  I was refering to the "meaning" that
make actually does use, not what it should use.

But I'd have to say that if make is restricted to talking only
about a single type of relationship between objects, then this
relationship (that is, X is used to create an instance of Y) is
exactly the right one for make to have.

On the other hand, I don't think make *should* be restricted to
talking only about a single type of relationship between objects.
The relationship Richard suggests (that is, the meaning of Y
changes if the meaning of X changes (and the meaning of any X
changes if the object X itself changes)) should be representable.

: Of course, once the meaning of "Y" has changed, any file "Z" that
: includes it also has had it's meaning changed.  Whether any process
: must be invoked when the meaning of a file has changed is a separate
: issue.

That's exactly why I introduce the suite of "virtual" or "conceptual"
objects *.[ch]+, which embody this secondary relationship (that is, "the
meaning of the corresponding *.[ch] changed") within the "constructs"
relationship.  If we ignore current make limitations, there are
naturally ways of calculating this relationship that don't involve the
extra objects, but I consider the general method of using the extra
objects in this calculation to be a good way of doing it, because of
some nice caching and locality advantages that can be gained over some
of the alternatives I have considered. 

But the "meaning changes" relationship is only ONE of MANY relationships
that need to be calculated by make in addition to the "instance changes"
one that it does now.  Consider, for example, the command line
used to construct the .o.  Or the version of the compiler used.
And on and on and on.

DSEE, as an example, already does essentially all of these things.
There is also a commercial son-of-DSEE-product on Unix, for those
wishing to use a commercial product with these capabilities.

However, I think that a *really* good make would allow the user to
specify any calculation at all be made to decide whether a new
instance of a given object needs to be created, not just a few
"canned" ones that somebody anticipated ahead of time.  Granted,
this can (sort of) be done using vanilla make by using auxiliary
files as I did in my example for the "meaning changes" relationship,
but it's both clumsy and inefficient to write this info as separate
files in the filesystem.

And finally, in addition to being able to describe any relationship
locally and efficiently, I think a good make should be able to 
interleave "makedep"-like dependency derivation with construction.

Why is that? Well, it allows the creation of makedep algorithms much
easier and more plugable, because you don't have to tell two different
tools that lex becomes c becomes o, you can just tell make how to scan c
files, and then scan the files after they are constructed.  That means
you your description of how to scan .c files doesn't have to be warped
to include precursor files.  Further, you don't have to worry that extra
include statements will be introduced by some processor: even if they
are, doing the scan interleaved with the construction is guaranteed to
catch it exactly right. 

The best example of this would be to have to have make and processors
managed by make to be co-routines.  That is, when a compiler performs an
"open" on an input file, it ought to imply a callback into make to bring
that file up to date.  (This could be done by having make and the
compiler co-operate, or by sliding a virtual filesystem underneath the
compiler and make, which would allow any old compiler or tool to be
plugged into such a scheme.)


I've been playing with make replacements that can do most of these
things.  The problem is, I haven't made them syntactically backwards
compatible with make, because the concepts really don't fit very well.
That's one reason I don't use dmake or gnumake or other extended
makes.  I am prejudiced into thinking that they are being extended
in the "wrong direction" in some vague, fundamental sense.

That is, to paraphrase Ross Perot, we know what the problems with
make are, and it doesn't need just a little tune-up, it needs
a major overhaul.


:: If dates were checked recursively this would not be possible.  
: Would not?  IS not.  It isn't doing this NOW!  And say I change
: a comment in a .h file 3 depends back, ok -- we recompile & get
: a new .o, but we can still avoid the relink w/ your suggested
: enhancement.  Let's find a make that handles BOTH of our suggestions!

No, I'm pretty sure this can be done in make today.  Let's say that

        a: b
                b2a
        b: c
                c2b

Then, if the file c is edited, and c2b notes that the new version of b
it creates is identical with the old one ("identical" according to some
comparison or other), then it can timestamp b the same as it was before,
and the rule b2a will not fire.  I know of people who use make and use
this trick to extract .h files from .c files, and prevent uneeded
recompilation by appropriate comparison of the resulting .h files with
the old instances.   (Perhaps some versions of make cache filetimes,
so this wouldn't work... ???)

On the other hand, if we have

        a: c
                c2a
        b: c
                c2b
        c: d
                d2c

and we want the d2c rule to decide that this change matters to the c2a
rule but not to the c2b rule, we can't do this with current make
(though I *do* know of a way to do this with my experimental tools...
though I don't currently bother with this sort of thing).

( Well, actually, we *can* do this under current make, by a relative of
  the trick I used for the "meaning changed" stuff, that is, introduce
  extra dummy files for "meaning of c changed relative to a" and
  "meaning of c changed relative to b", but this quickly becomes
  prohibitive.  Having the ability to represent arbitrary data with
  objects, a-la SHAPETOOLS AFS, (or also in some commercial products)
  makes this plausible.  Or put it this way: having only a timestamp
  as information about each object is far, far too restrictive. )

: The question still remains, wouldn't it be nice to have a make
: that worked correctly?  Again pointing to a problem in the specification
: that the original make was written to.  Perhaps the only problem was
: lack of forethought, and we all know about 20/20 hindsight....  That
: doesn't mean we have to stick to it forever and ever amen.  

Well...  maybe.  People haven't shown too much interest in extending
make in the directions I've been playing with.  Maybe I've just been
talking to the wrong people. 
--
Wayne Throop  ...!mcnc!dg-rtp!sheol!throopw