NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
bin/59962: make(1): grouped target rules for batch recipes
>Number: 59962
>Category: bin
>Synopsis: make(1): grouped target rules for batch recipes
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Feb 05 02:45:00 +0000 2026
>Originator: Taylor R Campbell
>Release: current, 11, 10, 9, ...
>Organization:
netbsd.c netbsd.h: foundation.y
>Environment:
>Description:
Tools like lex(1) and yacc(1) produce multiple output files
foo.c and foo.h from a single input file foo.l/.y. (Other
examples abound, like TeX, Heimdal compile_et, and so on.)
For _sequentiail_ make(1), this can be expressed with a rule
having multiple targets:
foo.tab.c foo.tab.h: foo.y
yacc -b foo foo.y
However, this doesn't work for _parallel_ make(1): it may
execute the same recipe twice for foo.tab.c and foo.tab.h
independently.
GNU make(1) has sprouted an alternative syntax `&:' to mean
that foo.tab.c and foo.tab.h are both produced simultaneously
by a single execution of the recipe (which, of course, can't
vary according to the target by using $@ or $* or similar), and
in parallel builds, it only executes the rule once for either
target:
foo.tab.c foo.tab.h &: foo.y
yacc -b foo foo.y
We should adopt this.
(I'm not entirely clear on why the traditional parallel
behaviour of multi-target `:' rules is useful, really, except
when it's actually a different recipe for each target because
it varies by ${.TARGET}.)
>How-To-Repeat:
$ cat Makefile
all: .PHONY
all: c
.if !make(clean)
.BEGIN:
echo 0 >counter
.END:
@case $$(cat counter) in \
0|1) echo ok;; \
*) echo -n clobbered: ''; cat counter; exit 1;; \
esac
.endif
clean: .PHONY
@-rm -f a b c
a b:
@exec 3>counter; flock 3; c=$$(cat counter); echo $$((c + 1)) >&3
echo hello >a
echo world >b
c: a b
echo done >c
$ make clean && make
echo 0 >counter
echo hello >a
echo world >b
echo done >c
ok
$ make clean && make -j4
echo 0 >counter
--- a ---
--- b ---
echo hello >a
echo world >b
--- a ---
echo hello >a
echo world >b
--- c ---
echo done >c
clobbered: 2
*** Error code 1
Stop.
make: stopped in /tmp/riastradh/20260204/test
$
>Fix:
Yes, please!
Home |
Main Index |
Thread Index |
Old Index