Re: Static multiple target rules

2010-03-31 Thread tom honermann

On 3/30/2010 2:14 AM, Edward Welbourne wrote:

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

I don't actually see that y.output serves any role in this; simply
remove every reference to it and your example should be clearer.
  
It actually does serve a roll for testing purposes.  Try the following 
with this test case:


   gmake clean
   gmake
   rm y.output
   gmake
   gmake

With GNU make 3.81, the second to last gmake invocation rebuilds 
y.output which also
rebuilds y.tab.h and y.tab.c, but y.tab.o (now out of date) doesn't get 
rebuilt.  An additional
gmake invocation is necessary to get everything up to date - which is 
not desirable behavior.

   y.tab.o: y.tab.c y.tab.h
  

I don't understand .INTERMEDIATE well enough to know why this chain
fails to lead to y.tab.o's rule being run after yacc.ts's rule has
been run, in your -j case.  Something strange is going on,
  
I think what is happening is that time stamps are being checked too 
early in some cases.
Make can't infer that y.tab.h, y.tab.c, and y.output are updated by the 
commands for
yacc.ts.  Depending on when it checks the time stamps for those files, 
it may see the
times before or after the commands for yacc.ts are run.  I recall seeing 
emails regarding
GNU make caching time stamps, so that could contribute to this.  
Parallel builds would
behave differently since a shared cache isn't used and each process 
would have to

check time stamps on its own.  So, behavior varies.


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: Static multiple target rules

2010-03-31 Thread tom honermann

On 3/29/2010 8:20 PM, Philip Guenther wrote:

Hmm.  SysV make has offered the desired feature with the syntax

b1 + b2 + b3: d1
touch -r $^ $@
  
Ah, thank you!  I wasn't aware of a precedent syntax for this feature.  
I definitely agree with
using this syntax over what I proposed for compatibility with sysV and 
(potentially) future
POSIX standardization if the sysV semantics are adequate.  I'll run some 
tests with the
Solaris 10 version and follow up with comparisons with the semantics I 
had proposed.

It appears the sysV implementation doesn't let you declare multiple
groups with a single rule, but that's not a restriction of the syntax
itself.  Yes, that syntax has a meaning in GNU make (treating '+' as a
target), but it's clearly not a portable name for a target.  (Indeed,
plus-sign is not part of the POSIX Portable Filename Character Set.)
  
I'm not sure if multiple groups has good use cases or not.  I proposed 
supporting it mainly
because I felt there was a clear, reasonable, and consistent behavior 
and specifying the behavior
felt important since the syntax didn't preclude it.  (similar to nested 
groups except that nested

groups don't seem to have a clear and reasonable behavior)

I suspect very few people would be upset by the inability to specify a 
target named '+'.  Those
that are impacted would likely be able to change the file/target name to 
something else.  However,
if there is substantial concern, than a backward compatibility option 
could be added to disable

the new semantics.


The proposed syntax already has a conflicting special meaning in GNU
make (multiple archive-member target) for what would be the common
case of a single group.  That is, this:

(b1 b2 b3): d1
whatever

currently means the b1, b2, or b3 members of any archive library
depend on d1 and are updated by running 'whatever'.  The fact that
it's a special syntax means that it's more likely to actually be in
use out there.  How will the proposed change affect Makefiles using
that syntax?
  
Are you sure about this syntax?  I can't find any descriptions of it in 
the GNU make manual.
I do see archive pattern rules with a syntax such as '(%.o): %.c', but 
no static rules like this.
I tried this syntax and gmake treated it as three separate targets: 
'(b1', 'b2', 'b3)'.  This suggests
we could use parenthesis for the syntax, but I have no objections to the 
sysV syntax.  As Eddy

pointed out, the sysV syntax avoids the issue of nested groups.

(While I don't think the sysV syntax is *great*, I personally think
it's a better choice than overloading the meaning of parentheses.)
  

Yup, I agree.  If only for compatibility.


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: Static multiple target rules

2010-03-31 Thread tom honermann

On 3/30/2010 2:08 AM, Edward Welbourne wrote:

(While I don't think the sysV syntax is *great*, I personally think
it's a better choice than overloading the meaning of parentheses.)



+1
It also avoids the problem of having to make sense of nesting, e.g.
  

   (b1 (c1 c2)): d1
  

True, but it introduces the problem of making sense of these:

   + b1 + b2 +: d1
   b1 + + b2: d1
   b1 + b2 b3: d1

Solaris 10 make appears to silently drop dangling and extra '+' 
connectors - which is convenient
for handling macros that are empty when expanded.  It also appears to 
silently insert missing
'+' connectors if there are any '+' connectors in the target group.  
Thus, I think Solaris make would

treat the following rules as equivalent to the ones above:

   + b1 b2: d1
   + b1 b2 b3: d1

___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: Static multiple target rules

2010-03-31 Thread tom honermann

On 3/31/2010 1:01 AM, tom honermann wrote:

True, but it introduces the problem of making sense of these:

+ b1 + b2 +: d1
b1 + + b2: d1
b1 + b2 b3: d1

Solaris 10 make appears to silently drop dangling and extra '+' 
connectors - which is convenient
for handling macros that are empty when expanded.  It also appears to 
silently insert missing
'+' connectors if there are any '+' connectors in the target group.  
Thus, I think Solaris make would

treat the following rules as equivalent to the ones above:

+ b1 b2: d1
+ b1 b2 b3: d1

Strike that.  It seems Solaris make does not insert '+' connectors and 
does support multiple target
groups.  This behavior can be seen with rules that fail to actually 
produce all group members.


   all: a1 a2 a3 a4

   clean:
   rm -f a1 a2 a3 a4

   d1:
   @touch $@

   a1 + a2 a3 + a4: d1
   touch $@

The above Makefile has two target groups: a1+a2 and a3+a4.  The group 
target rule however will only

build the current target.

   $ make clean
   rm -f a1 a2 a3 a4
   $ make a1 a2
   touch a1

Only a1 is built.  Solaris make assumes a2 was built as well (or treats 
it similar to GNU make .PHONY

targets)

   $ make clean
   rm -f a1 a2 a3 a4
   $ make a1 a3
   touch a1
   touch a3

Both a1 and a3 are built in this last case since a1 and a3 are not in 
the same group.


   $ make clean
   rm -f a1 a2 a3 a4
   $ make a1 a2 a3 a4
   touch a1
   touch a3
   $ make a1 a2 a3 a4
   `a1' is up to date.
   touch a2
   `a3' is up to date.
   touch a4

The first make invocation builds a1 and a3 and assumes a2 and a4 were 
built.  A second invocation

causes a2 and a4 to actually get built.

Tom.
___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: Static multiple target rules

2010-03-31 Thread tom honermann

On 3/30/2010 11:35 PM, tom honermann wrote:

On 3/29/2010 8:20 PM, Philip Guenther wrote:

Hmm.  SysV make has offered the desired feature with the syntax

b1 + b2 + b3: d1
touch -r $^ $@
  
Ah, thank you!  I wasn't aware of a precedent syntax for this 
feature.  I definitely agree with
using this syntax over what I proposed for compatibility with sysV and 
(potentially) future
POSIX standardization if the sysV semantics are adequate.  I'll run 
some tests with the
Solaris 10 version and follow up with comparisons with the semantics I 
had proposed.
I adapted my prior example for the sysV group target syntax and did some 
testing with

the Solaris 10 make implementation:

   all: y.tab.h y.tab.c y.output y.tab.o

   clean:
   rm -f y.tab.h y.tab.c y.output y.tab.o

   grammar.y:
   @touch $@

   y.tab.h + y.tab.c + y.output: grammar.y
   @echo Running yacc...
   @sleep 1
   @touch y.tab.h y.tab.c y.output

   y.tab.o: y.tab.c y.tab.h
   @echo Compiling y.tab.c...
   @sleep 1
   @touch $@

This worked as expected and I wasn't able to trigger any undesirable 
behavior.  Solaris
make seems to delay or recheck time stamps such that the following steps 
will cause
y.tab.o to be rebuilt.  Note that only y.output is out of date when the 
last make invocation
is made, but make recognizes that y.tab.h and/or y.tab.c has been 
rebuilt and therefore

regenerates y.tab.o as well.  Exactly what is desired.

   $ make
   $ touch grammar.y
   $ touch y.tab.h y.tab.c
   $ touch y.tab.o
   $ make
   Running yacc...
   Compiling y.tab.c...

I went on to evaluate some other behaviors using this example:

   Makefile:

   all: a1 a2 a3

   clean:
   rm -f a1 a2 a3

   d1:
   @touch $@

   a1 + a2 + a3: d1
   @echo   \$$@:$@
   @echo   \$$%:$%
   @echo   \$$(@D): $(@D)
   @echo   \$$(@F): $(@F)
   @touch -r d1 $@

   $ make clean
   rm -f a1 a2 a3
   $ make
 $@:a1
 $%:
 $(@D): .
 $(@F): a1

Note that $@ expanded to the first requested target (from the default 
'all' rule).

Separate commands were not run for targets a2 and a3.  Had the targets been
normal targets instead of group targets, the commands would have been run
three times each to generate a1, a2, and a3.

   $ make
 $@:a2
 $%:
 $(@D): .
 $(@F): a2

Note that 'make clean' was not run here.  The commands above did not
generate a2 during the first make invocation.  Make now notices this and
invokes the rule to build a2.

   $ make
 $@:a3
 $%:
 $(@D): .
 $(@F): a3

Same thing again.  Now we're all up to date.

Solaris make allows group members to be phony targets, but there are 
caveats.  The
example above shows that the implementation doesn't check to make sure 
all group
members were actually generated (which is good and consistent with 
normal phony
target rules).  However, here are is an example showing behavior which I 
find

somewhat baffling:

   all: b1 b2

   clean:
   rm -f b1 b2

   b1 + b2: d1
   @echo   \$$@:$@
   touch b1

Consider the following output:

   $ make clean
   rm -f b1 b2
   $ make b1 b2
 $@:b1
   touch b1
   `b2' is updated.

b1 was requested first.  b2, though not generated, is considered up to date.

   $ make clean
   rm -f b1 b2
   $ make b2 b1
 $@:b2
   touch b1
 $@:b1
   touch b1

In this case, b2 was requested first and the rules run.  However, 
Solaris make then
ran the rules again to generate b1.  I would have expected it to 
consider b1 up to

date once b2 was built.  The implementation apparently checks to see if the
requested target was actually completed and only considers the group up 
to date

if it was.

Solaris make (at least Solaris 10) does support multiple group targets.  
For an

example, see my most recent email to the mail list.

Solaris make does support archive members as target group members as well.

Solaris make has support for the .IGNORE and .SILENT special targets
however, prerequisites for these are only supported when the special .POSIX
target is also specified.  When running commands for a target group member,
the current target is used to determine whether the .IGNORE or .SILENT
behavior is in effect.  For example:

   all: i1 i2
   all: s1 s2

   clean:
   rm -f i1 i2 s1 s2

   .POSIX:
   .IGNORE: i2
   i1 + i2: d1
   @echo   \$$@:$@
   touch i1 i2
   exit 1

   .SILENT: s2
   s1 + s2: d1
   @echo   \$$@:$@
   touch s1 s2

In the following example runs, the current target is always the first 
one specified

on the command line.

   $ make clean
   rm -f i1 i2 s1 s2
   $ make i1 i2
 $@:i1
   touch i1 i2
   exit 1
   *** Error code 1
   make: Fatal error: Command failed for target `i1'

   $ make clean
   rm -f i1 i2 s1 s2
   $ make i2 i1
 $@:

Re: Static multiple target rules

2010-03-30 Thread Edward Welbourne
y.tab.h y.tab.c y.output: yacc.ts

I don't actually see that y.output serves any role in this; simply
remove every reference to it and your example should be clearer.

y.tab.o: y.tab.c y.tab.h

I don't understand .INTERMEDIATE well enough to know why this chain
fails to lead to y.tab.o's rule being run after yacc.ts's rule has
been run, in your -j case.  Something strange is going on,

Eddy.


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: Static multiple target rules

2010-03-29 Thread tom honermann

On 3/3/2010 2:03 AM, Edward Welbourne wrote:

Another possibility crossed my mind over-night, with which I haven't
experimented, but that seems like it theoretically should work.
Replace the touch-file with a phony rule:

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

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

Because it's phony, and we never create it, it'll never exist and make
shouldn't care that no such file exists; because the three real
targets depend on it, any need for any of them shall force it to be
made (causing them to all exist); but if more than one of them needs
made, an individual run of make shall only make the phony once yet
still know that it's made it, so not need to run yacc again for the
sake of the others that depend on it.

But I may be confused about proper use of .PHONY - please experiment
and report your results !

Eddy.
  

You're a genius!  .PHONY didn't do the trick, but .INTERMEDIATE did:

   .INTERMEDIATE: yacc.ts

   all: y.tab.h y.tab.c y.output y.tab.o

   clean:
   rm -f y.tab.h y.tab.c y.output y.tab.o

   grammar.y:
   @touch $@

   yacc.ts: grammar.y
   @echo Running yacc...
   @sleep 1
   @touch y.tab.h y.tab.c y.output

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

   y.tab.o: y.tab.c y.tab.h
   @echo Compiling y.tab.c...
   @sleep 1
   @touch $@

The only problem I could find with this approach is that downstream 
targets might not get rebuilt as expected.  For example, run gmake once 
to build everything, then remove y.output and run gmake again.  Using 
make 3.81 on Linux, y.output is rebuilt which also rebuilds y.tab.c and 
y.tab.h, but y.tab.o is not rebuilt (as might be expected since y.tab.h 
and y.tab.c were regenerated).  This makes sense because gmake has no 
way of knowing that rebuilding y.output would also regenerate y.tab.h 
and y.tab.c.  A full solution for static multiple target rules would 
recognize that these files had been regenerated and would also rebuild 
y.tab.o.  But, I think this is good enough for my use cases.


Thanks Eddy!
Tom.


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: Static multiple target rules

2010-03-29 Thread tom honermann

On 3/2/2010 5:18 PM, tom honermann wrote:

On 3/2/2010 2:45 AM, Edward Welbourne wrote:
I've been struggling for some time now with how to write rules for 
commands that generate multiple targets  

A familiar and annoying problem: make really believes in commands that
generate just one (relevant) file, and doesn't fit so well with ones
that generate several.  
And yet, pattern rules do have such support.  I'd love to see a syntax 
added to enable static
multiple target rules.  Since parenthesis are already treated 
specially in target names (for archive
rules), perhaps a syntax like the following could be used without 
harming backward compatibility.


   (y.tab.h y.tab.c y.output): grammar.y
   yacc -d -v $^
Paul, would you be opposed to a patch that implements support for static 
multiple target rules using
the above syntax?  Any particular concerns or requirements you would 
have?  I'm not sure when I

might find the time, but I might be able to put something together.

Here are some examples of how I think the functionality should work:

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

Any request for y.tab.h, y.tab.c, or y.output would result in a single 
execution of the rule.
Timestamps would be updated for all three targets regardless of which 
target(s) were
requested.  Parallel builds would recognize requests for any of these 
targets as requiring a

single invocation of the rule.

   a1 (b1 b2 b3): d1
   touch -r $^ $@

Note the space between 'a1' and the left parenthesis.  This is required 
so that the target is

not parsed as an archive member.

Any request for b1, b2, or b3 would again result in a single execution 
of the rule.  $@
would expand to include the set of all group targets regardless of which 
target(s) within
the grouping were requested.  For example, 'make b2 b3' would invoke 
'touch' exactly

once with $^ expanding to d1 and $@ expanding to b1 b2 b3.  Running
'make a1 b2' would invoke 'touch' twice.  Once for a1 and again for the 
b1 b2 b3 group.
To generate target a1, 'touch -r d1 a1' would be run.  To generate b2, 
'touch -r d1 b1 b2 b3'

would be run.

   (dir1/b1 dir1/b2 dir2/c1): d1
   echo $(@D)
   echo $(@F)

The directory and file-within-directory automatic variables would expand 
to lists of the relevant
parts.  For example, 'gmake dir1/b2' would echo dir1dir1 dir2 followed 
by b1 b2 c1.


   (b1 (c1 c2)): d1

I haven't come up with an appropriate behavior for groups within 
groups.  I suggest treating

this as a syntax error until someone comes up with a reasonable use case.

   (a1(foo1.o bar1.o) a2(foo2.o bar2.o)): d1
   echo $%
   echo $@

This can be treated as a single group consisting of four archive 
members: a1(foo1.o),
a1(bar1.o), a2(foo2.o) a2(bar2.o).  In this case, $% would expand to the 
list of archive

member names.  For example, running 'gmake a1(bar1.o)' would echo
foo1.o bar1.o foo2.o bar2.o. followed by a1(foo1.o) a1(bar1.o) 
a2(foo2.o) a2(bar2.o)


Handling of special targets requires more consideration since this could 
introduce conflicts.

.PHONY, .PRECIOUS, .INTERMEDIATE and .SECONDARY don't raise immediate
concerns for me.  But .IGNORE and .SILENT could create conflicting 
requirements.  I

see three options for dealing with these:
1: Ignore these attributes in these cases.
2: Use the attributes associated with the first element in the group list.
3: Use the attributes of the first group member for which gmake decides 
the rules must be run.


Note that the above syntax is similar to pattern rules for archive members:

   (%.o): %.c
   $(CC) $(CFLAGS) $(CPPFLAGS) -c $ -o $*.o
   $(AR) r $@ $*.o
   $(RM) $*.o

I haven't looked at the make source code yet to determine if this will 
create parsing complications

or ambiguities.

Tom.


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: Static multiple target rules

2010-03-29 Thread Philip Guenther
On Mon, Mar 29, 2010 at 7:54 PM, tom honermann tom.honerm...@oracle.com wrote:
 Paul, would you be opposed to a patch that implements support for static
 multiple target rules using the above syntax?
 Any particular concerns or requirements you would have?
...
   a1 (b1 b2 b3): d1
       touch -r $^ $@

 Note the space between 'a1' and the left parenthesis.  This is required so
 that the target is not parsed as an archive member.

Hmm.  SysV make has offered the desired feature with the syntax

b1 + b2 + b3: d1
touch -r $^ $@

It appears the sysV implementation doesn't let you declare multiple
groups with a single rule, but that's not a restriction of the syntax
itself.  Yes, that syntax has a meaning in GNU make (treating '+' as a
target), but it's clearly not a portable name for a target.  (Indeed,
plus-sign is not part of the POSIX Portable Filename Character Set.)


The proposed syntax already has a conflicting special meaning in GNU
make (multiple archive-member target) for what would be the common
case of a single group.  That is, this:

(b1 b2 b3): d1
whatever

currently means the b1, b2, or b3 members of any archive library
depend on d1 and are updated by running 'whatever'.  The fact that
it's a special syntax means that it's more likely to actually be in
use out there.  How will the proposed change affect Makefiles using
that syntax?

(While I don't think the sysV syntax is *great*, I personally think
it's a better choice than overloading the meaning of parentheses.)


Philip Guenther


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: Static multiple target rules

2010-03-03 Thread Edward Welbourne
 The only downsides to this I see are:

 1: The duplicate file storage.  Probably not a big deal.
 2: The extra processing time to archive and extract the files.  Again, 
 probably not a big deal.
 3: The why'd they do that? questions coming from people unfamiliar 
 with the technique.

all valid problems.

 4: It doesn't address that nagging feeling that make should be able to 
 support this.

Quite.

Another possibility crossed my mind over-night, with which I haven't
experimented, but that seems like it theoretically should work.
Replace the touch-file with a phony rule:

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

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

Because it's phony, and we never create it, it'll never exist and make
shouldn't care that no such file exists; because the three real
targets depend on it, any need for any of them shall force it to be
made (causing them to all exist); but if more than one of them needs
made, an individual run of make shall only make the phony once yet
still know that it's made it, so not need to run yacc again for the
sake of the others that depend on it.

But I may be confused about proper use of .PHONY - please experiment
and report your results !

Eddy.


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: Static multiple target rules

2010-03-02 Thread Edward Welbourne
 I've been struggling for some time now with how to write rules for 
 commands that generate multiple targets

A familiar and annoying problem: make really believes in commands that
generate just one (relevant) file, and doesn't fit so well with ones
that generate several.

 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

A quarter of an hour after reading your mail, I had a mildly perverted
idea: instead of a touch-file, use a tar-file !  The problem you point
to is when the touch file exists but the files we want don't: we need
a command for the rule that declares their dependency on it; and that
command needs to be able to generate the outputs from the fake file.

yacc.ts: grammar.y
yacc -d -v $^
tar cf $@ y.tab.h y.tab.c y.output

y.tab.h y.tab.c y.output: yacc.ts
tar xf $ -m

Note the crucial -m in the extracting tar, so that we touch the
outputs after the tar-file has been created, thereby avoiding
re-extracting every time we run make.

Not sure how well that'd work but it *looks* like it should ... and it
should generalise reasonably well.  Unfortunately I can't, just yet,
see how to turn it into a pattern rule for general .y file processing,

Eddy.


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: Static multiple target rules

2010-03-02 Thread Edward Welbourne
Correcting myself: I missed out the $@ in

y.tab.h y.tab.c y.output: yacc.ts
tar xf $ -m $@

which ensures that each target is the only thing extracted when the
rule to generate it is executed,

Eddy.


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


RE: Static multiple target rules

2010-03-02 Thread Martin Dorey
 instead of a touch-file, use a tar-file !

Yeah, one of my company's makefiles uses a similar intermediate file to good 
effect.  We've been using the touch-file or sentinel solution elsewhere for 
years.  I'd previously suggested replacing the sentinels with tar files so we 
could get rid of all the hackery we have to address the problem Tom raised 
about non-existent targets.  We have a macro that's used to convert missing 
source file names to the name of the corresponding sentinel file and then code 
to force that sentinel to rebuild.  It's complicated, ugly and fragile.

What really motivated me to reply, however, was:

 Note the crucial -m in the extracting tar

I would have made that mistake, so thanks for pointing it out before I stepped 
on the rake!

-Original Message-
From: bug-make-bounces+mdorey=bluearc@gnu.org 
[mailto:bug-make-bounces+mdorey=bluearc@gnu.org] On Behalf Of Edward 
Welbourne
Sent: Tuesday, March 02, 2010 02:45
To: tom honermann
Cc: bug-make@gnu.org
Subject: Re: Static multiple target rules

 I've been struggling for some time now with how to write rules for 
 commands that generate multiple targets

A familiar and annoying problem: make really believes in commands that
generate just one (relevant) file, and doesn't fit so well with ones
that generate several.

 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

A quarter of an hour after reading your mail, I had a mildly perverted
idea: instead of a touch-file, use a tar-file !  The problem you point
to is when the touch file exists but the files we want don't: we need
a command for the rule that declares their dependency on it; and that
command needs to be able to generate the outputs from the fake file.

yacc.ts: grammar.y
yacc -d -v $^
tar cf $@ y.tab.h y.tab.c y.output

y.tab.h y.tab.c y.output: yacc.ts
tar xf $ -m

Note the crucial -m in the extracting tar, so that we touch the
outputs after the tar-file has been created, thereby avoiding
re-extracting every time we run make.

Not sure how well that'd work but it *looks* like it should ... and it
should generalise reasonably well.  Unfortunately I can't, just yet,
see how to turn it into a pattern rule for general .y file processing,

Eddy.


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Re: Static multiple target rules

2010-03-02 Thread tom honermann

On 3/2/2010 2:45 AM, Edward Welbourne wrote:
I've been struggling for some time now with how to write rules for 
commands that generate multiple targets



A familiar and annoying problem: make really believes in commands that
generate just one (relevant) file, and doesn't fit so well with ones
that generate several.
  
And yet, pattern rules do have such support.  I'd love to see a syntax 
added to enable static
multiple target rules.  Since parenthesis are already treated specially 
in target names (for archive
rules), perhaps a syntax like the following could be used without 
harming backward compatibility.


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


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



A quarter of an hour after reading your mail, I had a mildly perverted
idea: instead of a touch-file, use a tar-file !  The problem you point
to is when the touch file exists but the files we want don't: we need
a command for the rule that declares their dependency on it; and that
command needs to be able to generate the outputs from the fake file.

yacc.ts: grammar.y
yacc -d -v $^
tar cf $@ y.tab.h y.tab.c y.output

y.tab.h y.tab.c y.output: yacc.ts
tar xf $ -m $@

Note the crucial -m in the extracting tar, so that we touch the
outputs after the tar-file has been created, thereby avoiding
re-extracting every time we run make.

Not sure how well that'd work but it *looks* like it should ... and it
should generalise reasonably well.  Unfortunately I can't, just yet,
see how to turn it into a pattern rule for general .y file processing,

Eddy.
  
Nice idea!  I like this much better than the workaround I had used 
involving $(shell...) and removing

the time-stamp file.  The only downsides to this I see are:

1: The duplicate file storage.  Probably not a big deal.
2: The extra processing time to archive and extract the files.  Again, 
probably not a big deal.
3: The why'd they do that? questions coming from people unfamiliar 
with the technique.
4: It doesn't address that nagging feeling that make should be able to 
support this.


Tom.


___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make


Static multiple target rules

2010-03-01 Thread tom honermann
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.



___
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make