jack: (Default)
[personal profile] jack
Suppose, hypothetically, I have a program "foo" which produces either or both of "apple.out" or "berry.out" from "apple.in" and "berry.in", and I wish to include an instruction in a makefile something like:
apple.out berry.out : apple.in berry.in
    foo apple.foo berry.foo
However, there's significant processing involved in running foo at all, and also in using an additional input file, so we wish to invoke foo once, with only the command line options necessary.

Is there any way to do so with a makefile?

I thoguht of two ways. Firstly, using conditionals and text-processing in the makefile to scan the targets requested on the command line, and if both "apple.out" and "berry.out" are requested, replace them with a phony target, something like "both.out", and then have separate rules for each of three possible targets. But does that work if one of the output files is not requested, but is a dependency of something else?

Secondly, using a temporary files to request invocation of "foo", say have a phony dependency of "apple.out" that creates a file "wantapple", and then a little fiddling to invoke "foo" with the names of those temporary "want" files, and then delete them. And an order-only dependency to ensure the temporary files are created before "foo" is invoked (if it is invoked at all).

But neither solution is at all elegant. Is there an approved way of doing so? Or is the approved way to stop being stubborn and use a program rather than make to do the decision making? A quick bit of research online produced no definitive answers, though several people asked about programs which always produced both outputs.

Edit: Yes, I wasted too long wondering about this when I ought to have just ignored it, rebuilt both every time, and got on with things :)

Date: 2009-01-05 09:40 pm (UTC)
From: [identity profile] crazyscot.livejournal.com
Sounds a bit like a slow Java compiler. If that's the case, at nC we punted and just rebuilt the entire set of classes in a single invocation (javac @myclasseslist) if any of the dependencies (the makefile-making script essentially did find . -name *.java) had changed. I'm led to believe that other make systems such as Ant might offer something nicer in this sort of situation, but I have no experience of them.

Date: 2009-01-05 10:02 pm (UTC)
From: [identity profile] cartesiandaemon.livejournal.com
Not specifically (it's a c program I have here, and in fact, almost all of the time you DO want to rebuild all the outputs, and in fact, B is quick enough you could just always build the two separately anyway, I'm just stubborn), but yes, exactly.

Date: 2009-01-05 10:11 pm (UTC)
ext_8103: (Default)
From: [identity profile] ewx.livejournal.com

The usual idiom is:


apple.out: apple.in berry.in
  foo apple.foo berry.foo

berry.out: apple.out

NB that listing multiple targets on the LHS doesn't do what (most) people seem to think it does.

Date: 2009-01-05 10:17 pm (UTC)
From: [identity profile] cartesiandaemon.livejournal.com
Yeah, that would accurately describe what it does. Though it doesn't help it do what I want it to do :)

NB that listing multiple targets on the LHS doesn't do what (most) people seem to think it does.

Yeah, so my research confirmed.

Date: 2009-01-06 11:12 am (UTC)
simont: A picture of me in 2016 (Default)
From: [personal profile] simont
I'm curious to know what the .foo files are, and in particular why they aren't also dependencies of the output files.

Date: 2009-01-06 11:35 am (UTC)
From: [identity profile] cartesiandaemon.livejournal.com
Oh, oops. I changed ".foo" to ".in", but didn't finished the job.