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
$@: >i2<
touch i1 i2
exit 1
*** Error code 1 (ignored)
`i1' is updated.
Note that the error was not ignored when the 1st target was i1, but the
error was
ignored when the 1st target was i2.
$ make clean
rm -f i1 i2 s1 s2
$ make s1 s2
$@: >s1<
touch s1 s2
exit 0
`s2' is updated.
$ make clean
rm -f i1 i2 s1 s2
$ make s2 s1
$@: >s2<
`s1' is updated.
Note that commands were echoed when the 1st target was s1, but were not when
the 1st target was s2.
The differences in the Solaris make implementation vs what I had
proposed include:
1: Obvious syntax differences. The Solaris syntax prohibits nested
groups which
is likely a good thing.
2: I had proposed that $@ and $% expand to include a list of all the
target group
members. Solaris make expands these to only include the current
target. For
compatibility, it makes the most sense to follow the Solaris model.
Additional
variables could be introduced that expand to the list of all targets
(ie, $(@^)) or
archive members (ie, $(%^)) and perhaps another set of variables that
expands
to the list of targets that are out of date (ie, $(@?) and $(%?)).
Combinations
for selecting directory and file parts would be possible as well: $(@^D) and
$(@^F) for example.
3: I had offered three possibilities for handling special targets that
could have
conflicting settings across group members. The Solaris make implementation
uses the third possibility I mentioned - using the attributes associated
with the
current target (the group member first requested). This makes sense to me.
All in all, the Solaris make implementation makes sense to me and would
fit my
needs. The only part about it that I feel concern about is how it
handles phony
target group members. But, there may not be good use cases for phony
members.
I couldn't find any documentation addressing this for the Solaris make
implementation.
Tom.
_______________________________________________
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make