[Top][All Lists]

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

Re: pattern rules with multiple targets producing intermediate files

From: Jan Beulich
Subject: Re: pattern rules with multiple targets producing intermediate files
Date: Wed, 22 Feb 2023 12:16:52 +0100
User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.8.0

On 19.02.2023 15:06, Paul Smith wrote:
> On Tue, 2023-02-07 at 14:51 +0100, Jan Beulich wrote:
>> 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).
> Unfortunately the above is hard for me to understand and trying to
> reproduce the behavior you're concerned about with the makefile you
> provided didn't yield success.

Looks like there was a timing issue which I needed to make one further
small adjustment for, to behave more predictably. The .c -> .o rule
wants to be

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

(i.e. the half-second sleep added there). I'm sorry for not noticing
this earlier.

> It would be very helpful if you could (A) explain how to set up the
> environment (I assume I need to "touch tst_a.a tst_b.b"?  Anything
> else?), (B) show a transcript of the commands you ran and the output
> you got, cut and pasted, and (C) point out very clearly in the output
> which things you think are not correct, and what you expected to happen
> instead.

There should be tst_a.a and tst_b.b plus, respectively up-to-date (i.e.
newer) tst_a.h, tst_b.c, and tst_b.h. Then "make -j2" gives

make: Entering directory '/home/jbeulich/tmp/mktst'
C: *=tst_b @=tst_b.o <=tst_b.c
sleep .5
A: *=tst_a @=tst_a.c <=tst_a.a
rm -f tst_a.[ch]
touch tst_a.c tst_a.h
sleep 1
Empty: tst_a.h
echo "tst_a.c (tst_a.a)" >tst_a.c
sleep 1
echo "tst_a.h (tst_a.a)" >tst_a.h
C: *=tst_a @=tst_a.o <=tst_a.c
sleep .5
rm tst_a.c
make: Leaving directory '/home/jbeulich/tmp/mktst'

This shows that the commands to "compile" tst_b.c and the commands to
re-generate tst_a.[ch] run in parallel; note the "Empty: ..." line,
which is what I'd expect to not be there (besides the expectation of
other output to be in different order). This is despite the Makefile
containing enough information for make to know that tst_a.h, being a
dependency of tst_b.o, is to be re-generated.

All this said, others involved in the investigation of the issue the
example was stripped down from meanwhile expressed the opinion that
the behavior is to be expected. Personally I remain unconvinced of
this, primarily because - as said - make has all information
available. It merely doesn't use it (yet maybe, as per the other
views expressed, rightly so).

FTAOD I'm attaching the full Makefile I've been using.


Attachment: Makefile
Description: Text document

reply via email to

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