guy (04/20/83)
We brought the System III "make" up on our VAX, mainly because it has significant enhancements for large projects. The primary one I have questions about here is the interface to SCCS. We extended that so it would work with RCS as well (we had to add rules to turn "foo.c.v" into "foo.o", or "foo.y.v" into "foo.o", etc. Just storing "foo.c" in "foo.v" and letting "make"'s normal suffix oriented rules doesn't work if you have to deal with ".y" as well as ".c".). I did this by adding rules with "%" in them, which acted analogously to the SCCS rules with "~" in them. Another person here was setting up a Makefile with a modified ".c.o" rule; he found that if you kept things in RCS (or SCCS) that you had to modify the ".c%.o" or the ".c~.o" rule as well, so that changes to a compilation rule had to be made more than once if you wanted to use RCS or SCCS. It turns out that "make" has TWO ways of doing "get"s (henceforth, I will refer only to SCCS and use SCCS terms); the first is through the ".c~.o" rules, which tell how to turn "s.foo.c" into "foo.o" by doing a "get", a "cc", and a "rm" of the gotten source. The second is used to "get" the Makefile from s.Makefile; this is NOT done by any explicit rules, but by a call to a routine "get". It turns out, after some poking around and a bit of work on "make", that this routine is used in other places; IF you specify the "-g" flag to "make", and if it is trying to make something and can't make it any other way, it will look for "s.whatever" and run "get" on that file. My questions: 1) Why isn't this used universally? I have modified "make" so that this rule is applied almost any time; that way, there is no need for a ".c~.o" rule. It merely tries to make "foo.o", looks to see if there is a matching "foo.c", finds none, looks for a matching "s.foo.c", finds it, calls "get" (which runs a "get" command on "s.foo.c" AND marks "foo.c" to be unlinked by "make" when it exits), and then says it found a matching "foo.c" and proceeds from there. This means that any normal compilation rule automatically has an SCCS version, without having to add the "~" kludge in order to have a transformation rule which isn't a strict suffix rule. Furthermore, the "get" routine automatically uses the "make" variable "RELEASE" as the release number to get (if supplied), only unlinks the gotten file when "make" exits (so that you don't have to get it multiple times if it is needed multiple times), AND, if the file to be gotten is in another directory, does a "cd" to that directory before doing the "get" (so that if it's trying to get "../headers/mumble.h" it does "cd ../headers; get s.mumble.h"). All this sounds very nice. Is there some catch that explains why this wasn't done? Note that since the "-g" option is always on, I changed the "-g" option to turn on a flag (already in "make", but not accessible through the command line) which tells it not to unlink any gotten files. 2) Another problem is that "make"s rules for how to make something are affected by the contents of the Makefile in non-obvious ways. If it's trying to make "foo.o", and there is no explict rule for making "foo.o", it looks for "*foo.*" in the current directory. But, even if there is no "foo.c" in the current directory, if it encountered "foo.c" ANYWHERE in a "make" rule in the Makefile it will try to make "foo.c" first. So, if you have "s.foo.c" and no "foo.c" nor "foo.o", it will make "foo.o" by first making "foo.c" by the ".c~.c" rule, and then making "foo.o" by the ".c.o" rule. This means that it doesn't clean up after itself by removing "foo.c", as the ".c~.c" rule doesn't remove the ".c" file that was the target of the ".c~.c" operation. Is there a reason why "make" decides that it should make "foo.c" even though it doesn't need to? If the new scheme (as above) is used, there won't be any rule for making "s.foo.c" into "foo.c"; it will merely know that if there is no "foo.c", it should do a "get" on "s.foo.c" AND that it should remove "foo.c" when the smoke clears. Guy Harris RLG Corporation {seismo,mcnc,we13}!rlgvax!guy