tags:

views:

79

answers:

2

I am attempting to do the following. There is a program, call it foo-bin, that takes in a single input file and generates two output files. A dumb Makefile rule for this would be:

file-a.out file-b.out: input.in
    foo-bin input.in file-a.out file-b.out

However, this does not tell make in any way that both targets will be generated simultaneously. That is fine when running make in serial, but will likely cause trouble if one tries make -j16 or something equally crazy.

The question is whether there exists a way to write a proper Makefile rule for such a case? Clearly, it would generate a DAG, but somehow the GNU make manual does not specify how this case could be handled.

Running the same code twice and generating only one result is out of the question, because the computation takes time (think: hours). Outputting only one file would also be rather difficult, because frequently it is used as an input to GNUPLOT which doesn't know how to handle only a fraction of a data file.

+1  A: 

I would solve it as follows :

file-a.out: input.in
    foo-bin input.in file-a.out file-b.out   

file-b.out: file-a.out
    #do nothing
    noop

In this case parallel make will 'serialize' creating a and b but since creating b does not do anything it take no time.

Peter Tillemans
Actually, there is a problem with this. If `file-b.out` was created as stated and then mysteriously deleted, `make` will be unable to recreate it because `file-a.out` will still be present. Any thoughts?
makesaurus
+2  A: 

The trick is to use a pattern rule with multiple targets. In that case make will assume that both targets are created by a single invocation of the command.

all: file-a.out file-b.out
%-a.out %-b.out: input.in
    foo-bin input.in $*-a.out $*-b.out

This difference in interpretation between pattern rules and normal rules doesn't exactly make sense, but it's useful for cases like this, and it is documented in the manual.

slowdog
This actually isn't correct.Your rule specifies that files matching these patterns are to be made from input.in using the command specified, but nowhere does it say that they are made simultaneously. If you actually run it in parallel, `make` will run the same command twice simultaneously.
makesaurus
Please try it before you say it doesn't work ;-)The GNU make manual says: "Pattern rules may have more than one target. Unlike normal rules, this does not act as many different rules with the same prerequisites and commands. If a pattern rule has multiple targets, make knows that the rule's commands are responsible for making all of the targets. The commands are executed only once to make all the targets." http://www.gnu.org/software/make/manual/make.html#Pattern-Intro
slowdog