Hi Eric, Thanks for all your comments (public and private)!
>>> "Eric" == Eric Siegerman <[EMAIL PROTECTED]> writes: Eric> On Sat, Jan 31, 2004 at 11:28:29PM +0100, Alexandre Duret-Lutz wrote: >> One of the output (here `data.c') is used as a witness of the run of >> `foo'. [...] Eric> Hmm. I understand what you're saying here, but "witness" seems Eric> an odd choice of words to say it. I can't think of a better one Eric> offhand, though. What's the French word you're trying to Eric> translate? témoin = { witness, indicator, evidence } Perhaps evidence is better? >> What we need is a rule that forces a rebuild when data.h is missing. >> >> data.c: data.foo >> foo data.foo >> data.h: data.c >> @if test -f $@; then :; else \ >> rm -f data.c; \ >> $(MAKE) $(AM_MAKEFLAGS) data.c; \ >> fi >> Eric> I believe this fails on the following corner case. Suppose the Eric> date ordering is like this (with data.h being the oldest): Eric> data.h data.foo data.c Eric> data.h is out of date with respect to data.foo, so one wants to Eric> rebuild it, On the other hand, data.c is newer than data.foo, so one does not want to overwrite it. (For instance one could be hand editing the generated data.c file to insert precious debugging statements.) Running foo could fix a user error (who messed the timestamps badly), but it could also erase some user work. It's not clear to me whether there is a right thing to do here. [...] Eric> I'm tempted to suggest that any make program that does Eric> the redundant "foo" execution (in a non-parallel build) Eric> is buggy, and the problem is benign anyway. When I wrote that text I tried to remember where I had seen this behavior but I could not. I recall I've suffered from redundant executions in some hand-written project, but I'm not even sure it was the same problem. I've tried to reproduce this with a few make implementations (GNU, BSD, Solaris, OSF) unsuccessfully. Beside parallel builds, I thought of another situation where multiple target rules may cause redundant executions: it can also happen when one of the dependency is phony. Consider the following horror: .PHONY: buildtime.h buildtime.h: echo "#define build_time \"`date`\"" > $@ data.c data.h: data.foo buildtime.h foo data.foo Adding `data.c: data.h' will not be enough here. Eric> If the naive approach doesn't work, live with it or get a Eric> better "make". That's something I'd really hate to write in the manual of a tool that aim at writing portable Makefiles :) Eric> As for parallel builds, how about this variation: Eric> data.c data.h: data.foo Eric> foo data.foo Eric> data.h: data.c Apart from the PHONY example above, and the right thing debate, I don't see anything wrong with it. It certainly looks more pleasant. I guess we'll have to extend the section to document the two styles, since there are pro an cons for both. [...] Eric> This scales to multiple outputs too, but it gets a bit ugly, since Eric> one has to impose a serial ordering on all of them: Eric> data.c data.h data.x data.y: data.foo Eric> foo data.foo Eric> data.h: data.c Eric> data.x: data.h Eric> data.y: data.x That's seems less easy to maintain, though. For instance consider the following way to perform all-at-once compilations: ELFILES = one.el two.el three.el four.el elc-stamp: $(ELFILES) @rm -f elc-temp @touch elc-temp $(elisp_comp) $(ELFILES) @mv -f elc-temp $@ $(ELFILES:=c): elc-stamp @if test -f $@; then \ touch $@; \ else \ rm -f elc-stamp; \ $(MAKE) $(AM_MAKEFLAGS) elc-stamp; \ fi Adding more files to compile requires just an update of ELFILES. Another point is conditional compilations. Here they simply require a conditional definitions of ELFILES. If a total ordering of outputs was required, I believe it would have to be computed for all possible combinations of conditions. Eric> I haven't tested either of these approaches; just Eric> throwing them out for consideration. Thanks again for doing this! -- Alexandre Duret-Lutz