bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Static multiple target rules


From: tom honermann
Subject: Static multiple target rules
Date: Mon, 01 Mar 2010 18:14:25 -0800
User-agent: Thunderbird 2.0.0.23 (Windows/20090812)

I've been struggling for some time now with how to write rules for commands that generate multiple targets and I have so far been unable to find an elegant solution that works reliably. I know pattern rules have support for specifying multiple targets, but they don't seem to be appropriate for all scenarios.

As an example, lets consider the venerable 'yacc' command:

   yacc -d -v grammar.y

This will produce the following files:  y.tab.h, y.tab.c, and y.output

Myself and many others have naively tried a rule like the one below and then been surprised to see 'yacc' get invoked multiple times (especially in parallel builds).

   y.tab.h y.tab.c y.output: grammar.y
       yacc -d -v $^

The fine GNU make manual describes this syntax and its behavior well (section 4.10 - "Multiple Targets in a Rule" in the manual I'm looking at). This syntax and behavior are very useful - just not for specifying multiple targets for a single command!

The next thing to try is using a proxy or timestamp file:

   yacc.ts: grammar.y
       yacc -d -v $^
       touch $@

   y.tab.h y.tab.c y.output: yacc.ts

This solves the problem of 'yacc' getting run multiple times while preserving the desired behavior that 'yacc' is only invoked when its targets are out of date. However, if 'yacc.ts' exists, is newer than 'grammar.y', and any of 'y.tab.h', 'y.tab.c', or 'y.output' do not exist, then 'yacc' won't get run to re-generate them (since make sees that 'yacc.ts' is up to date and concludes that the other targets must be up to date as well).

A solution for that last problem might look something like this:

   $(shell [ -f y.tab.h -a -f y.tab.c -a -f y.output ] || rm -f yacc.ts)

   yacc.ts: grammar.y
       yacc -d -v $^
       touch $@

   y.tab.h y.tab.c y.output: yacc.ts

This works, but is rather inelegant - especially if there are many more output files than in my simple example. Is there a better way to write rules for generating multiple targets such as this? Has anyone proposed extensions to GNU make to support static multiple target rules?

Tom.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]