benson@ksr.UUCP (Benson Margulies) (02/27/89)
This message is directed to the mk experts/authors on the net, if any. (mk is an alternative make tool available via the AT&T toolchest). It seems impossible to set up a regular expression metarule in mk that will permit dependencies of the form: foo.o : ../x/foo.c The regular expression (not to mention the % rules) insist that the source pathname be built entirely out of literals and pieces of the target. There is no provision for the source containing things that the target lacks. One could try to write: '\(.*\)\.o' :R: '.*\1.c' but that won't work, since the source is not regexp matched, it is only regexp expanded from the target. This is a fairly common thing to want to do. In nmake, the .SOURCE targets often obviate it by allowing searching for sources. Does anyone know a trick that I don't? Is there some theory at work here? -- Benson I. Margulies Kendall Square Research Corp. harvard!ksr!benson benson@ksr.com
andrew@alice.UUCP (Andrew Hume) (03/01/89)
In article <518@ksr.UUCP>, benson@ksr.UUCP (Benson Margulies) writes: > It seems impossible to set up a regular expression metarule > in mk that will permit dependencies of the form: > > > foo.o : ../x/foo.c > > The regular expression (not to mention the % rules) insist that the > source pathname be built entirely out of literals and pieces of the > target. There is no provision for the source containing things that > the target lacks. > > One could try to write: > > '\(.*\)\.o' :R: '.*\1.c' > > but that won't work, since the source is not regexp matched, it > is only regexp expanded from the target. This is a fairly common > thing to want to do. In nmake, the .SOURCE targets often obviate it > by allowing searching for sources. > > Does anyone know a trick that I don't? Is there some theory > at work here? > -- > Benson I. Margulies Kendall Square Research Corp. > harvard!ksr!benson benson@ksr.com This is a very incisive question that points out one of mk's awkwardnesses. But as we shall see, mk isn't the only one. The theory (such as it is) is that glob expansion is done on reading the mkfile and as the metarules have not had their % or \\1 expanded, it would be pointless to do glob expansion on them as well as being ambiguous (does the * mean a glob * or a reg exp *). As Benson points out, the real difficulty is that information can only decrease going from target to dependents. It is constructive to understand what is going on here. The canonical example is the mkfile for libc. For simplicity, assume that libc.a is made from pow.o (made from math/pow.c) and abs.o (made from gen/abs.c). The question is how to construct a mkfile with the minimal amount of information? I am not really too proud of the solution i use for our libc but it does work and is succint: OBJ=libc.a(abs.o) libc.a(pow.o) libc.a:Q: $OBJ names=`membername $newprereq` ar rv libc.a $names && rm $names ranlib libc.a pow.o: math/pow.c abs.o: gen/abs.c $L(%.o):N: %.o %.o: cc -O -c $prereq ld -o $nproc.o -x -r $target && mv $nproc.o $target Apart from the normal mucking around to do the library correctly this is quite short. you have to say the element names once and you have to say where the source is. (at least, that is my taste so as to avoid problems with multiple answers to pow.o: */pow.c.) The slime in this mkfile is the rule for %.o; the prerequisites come from the xx.o: yy/xx.c in a somewhat sleazy indirect manner. How do other makes handle this problem? nmake does it by the equivalent of viewpathing with all the glories and problems of that technique; the main problem being that you have to have a database to get the right answer as the filesystem doesn't hold enough information to deal with the case of generating a foo.o from a foo.c; removing that foo.c and uncovering an older foo.c. According to the dates, foo.o is okay but it ain't the foo.o i married. gnumake does it by a curious rule that makes little sense on its own but is really useful here; when you say %.o: %.c, the % on the right is not the same as the % on the left, it is actually basename(%). or at least, it is sometimes. in summary, i am not proud of how mk does it but i think it does it honestly. if viewpathing is your game, use nmake. gnumake can support it by special purpose hack but at the cost of ruining the meaning of % (for example, if gnumake ever does transitive closure, what value of % is used?). if you have cycles to burn, you might try cake. it has rather a different slant on things and evaluates predicates etc before deciding to use rules so you should be able to do something clever.