bug-make
[Top][All Lists]
Advanced

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

pattern rules with multiple targets producing intermediate files


From: Jan Beulich
Subject: pattern rules with multiple targets producing intermediate files
Date: Tue, 7 Feb 2023 14:51:30 +0100
User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.7.1

Hello,

while something has changed from 4.3 to 4.4 in the dealing with
intermediate files, the example Makefile below still doesn't work
as expected. There are two pairs of *.[ch] files generated, each by
their respective rule. Each of the *.o files to be compiled from the
*.c ones has a dependency recorded on both *.h files. If (up-to-date
or outdated) instances of all four generated files are there, all is
fine. If both *.c files are missing, all is fine as well. However,
if only one *.c file is missing and the other is up-to-date,
compilation of the other *.c file will (provided at least -j2 was
passed) be invoked in parallel to the re-generation of the other
*.[ch] pair, not taking into consideration that one of the *.h files
is in the process of being re-generated (together with its sibling
*.c file).

The difference in behavior of 4.4 compared to 4.3 is that this is
now symmetric. In 4.3 only the C file corresponding to the first
prereq of "all" was permanently affected by the bad behavior
(according to my experiments); a re-run of make would succeed
(because the intermediate file was not treated as such and hence was
not deleted).

Of course I'm not going to exclude that there's something that's
done wrongly in that (heavily stripped down) example - apologies in
advance if so, yet then I'd still appreciate if it could be pointed
out what needs doing differently.

Jan

.PHONY: all
all:    tst_b.o tst_a.o

Makefile:: ;

tst_b.o tst_a.o: tst_a.h tst_b.h

#.SECONDARY: tst_a.c tst_b.c

%.o: %.c
        @echo 'C: *=$* @=$@ <=$<'
        @for i in $^; do test -f "$$i" || echo "Missing: $$i"; done
        @for i in $^; do test -s "$$i" || echo "Empty: $$i"; done

%.c %.h: %.a
        @echo 'A: *=$* @=$@ <=$<'
        rm -f $*.[ch]
        touch $*.c $*.h
        sleep 1
        echo "$*.c ($<)" >$*.c
        sleep 1
        echo "$*.h ($<)" >$*.h

%.c %.h: %.b
        @echo 'B: *=$* @=$@ <=$<'
        rm -f $*.[ch]
        touch $*.c $*.h
        sleep 1
        echo "$*.c ($<)" >$*.c
        sleep 1
        echo "$*.h ($<)" >$*.h



reply via email to

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