Hi Paul, > There is a straightforward and portable way to do this even with > traditional make, it's just not as nice (but, nicer than changing all > the recipes to use test IMO! :)). > > If you have a rule like this: > > <a1> <b2> ... : <prereqs> > <command> > > where <command> generates all targets with one invocation, then your > best bet is to modify this rule into two rules: > > <a1> <b2> ... : .sentinel ; > > .sentinel: <prereqs> > <command> > @touch $@ > > Note, it's critical to include the semicolon here. Or if you prefer to > be more explicit you can write something like: > > <a1> <b2> ... : .sentinel > : do nothing > > This will work properly.
Thanks for showing this idiom. I think this can be improved a bit: Instead of 'touch .sentinel' I would use 'echo > .sentinel'. Because if you use 'touch .sentinel' and the build directory is on an NFS mount and the clock of the NFS server is ahead the clock of localhost (I have seen this quite frequently), the timestamp of .sentinel will be behind the timestamp of the newest <prereqs>, and thus another "make" run will execute the rule again. Still, I don't like these '.sentinel' or stamp files, because they add complexity: * The developer has to decide whether the stamp file should go into the build dir or $(srcdir). The general rule should be that if <command> uses only build tools that are guaranteed to be present, then <a1> <b2> ... and the stamp file should go into the build dir, whereas if they use less common tools (e.g. bison), they should all go into $(srcdir). * The automake dist target needs to be adjusted to include this stamp file. * Version control (.gitignore) needs to be adjusted to include this stamp file. I'll use the rule with a phony target and 'test ... -ot ...', unless you find a problem with it (other than the potential portability problem redarding 'test'). Bruno