On Mon, 2007-04-09 at 16:20 -0700, Ben Wilhelm wrote:
a b c d: source.flag
@true
source.flag: source
( touch source.flag && blackbox_generate a b c d ) \
|| ( rm -f source.flag && false ) # eugh
but this is horribly ugly, although it does work. (I think the @true is
necessary but to be honest I'm hazy as to why, although it doesn't
rebuild the things that depend on a b c d without it.)
You can write this much more cleanly, like this:
a b c d: .source_flag
@:
.source_flag: source
blackbox_generate a b c d
@touch .source_flag
Is there a good solution to this? Ideally one without extra temporary
files? While I know why the first case doesn't work ("A rule with
multiple targets is equivalent to writing many rules, each with one
target, and all identical aside from that." from 4.10 in the make
manual) I haven't been able to figure out how to get the behavior I want.
There are only two ways to do what you want. The one above works for
all types of targets.
The other way is to use pattern rules: if your targets and a
prerequisite share a stem that can be matched by a pattern ("%"), then
you can write:
%a %b %c %d: %source
blackbox_generate $*a $*b $*c $*d
Unlike explicit rules, pattern rules with multiple targets behave as you
are looking for: they build all the targets with one invocation of the
command script.
If you can't use pattern rules then you must use temporary files, sorry.
Although the method I show above is much cleaner, and users will
probably not notice the difference.