|
Boost-Build : |
Subject: Re: [Boost-build] bjam handling of temps
From: Stefan Seefeld (stefan_at_[hidden])
Date: 2017-11-03 17:00:52
On 03.11.2017 12:43, Steven Watanabe via Boost-build wrote:
> AMDG
>
> On 11/03/2017 09:35 AM, Stefan Seefeld via Boost-build wrote:
>> I'm investigating an issue with bjam's handling of temporaries. It seems I'm
>> still not understanding how bjam handles them. Consider this code snippet:
>>
>> actions make {
>> touch $(<)
>> }
>>
>> actions cat {
>> cat $(>) > $(<)
>> }
>>
>> make A ;
>> cat B : A ;
>> cat C : A ;
>> cat D : B C ;
>>
>> TEMPORARY B ;
>>
>> DEPENDS B : A ;
>> DEPENDS D : B C ;
>>
>> UPDATE D ;
>>
>>
>> Running `bjam` on this the first time creates A, B, C, and D, as expected.
>> Calling it again updates D again, and I don't understand why. If I remove the
>> TEMPORARY flag on B, D isn't updated, so this forceful update of D seems to be
>> caused by B being a temp.
>>
>> The second issue seems even more serious: if I remove B, and call bjam again,
>> nothing is updated, as expected. But if I remove B and C and call bjam, I get an
>> error as D is attempted to be updated after C is remade, but B wasn't updated
>> (it's marked "temporary stable" in the debug output). Why isn't B updated first ?
>>
>> The logic in make.c suggest's that, despite B's binding is set to PARENT (i.e.,
>> D), its fate is determined before that of D, and thus is found to be stable,
>> even though a little later D's fate is set to update. Shouldn't a temporary's
>> fate be determined *after* its parent ?
>>
>> What am I missing ?
>>
> Two things:
>
> First of all, a TEMPORARY target is supposed to be
> deleted:
>
> actions RmTemps {
> rm $(>)
> }
> ...
> cat D : B C ;
> RmTemps D : B ;
>
> Rebuilding when a temporary is present seems to be
> deliberate, though I'm not quite clear on the logic
> behind this.
> #define T_FATE_SPOIL 4 /* >= SPOIL rebuilds parents */
> #define T_FATE_ISTMP 4 /* unneeded temp target oddly
> present */
Yeah, I have wondered about that, too. I think this is manifest in code
as
https://github.com/boostorg/build/blob/develop/src/engine/make.c#L621-L624,
which I have tentatively commented out, as I don't follow the rationale
of existing temps being considered tainted. (Quite the opposite,
actually: if I keep a temp around, perhaps I'm in the middle of a debug
session where I do want to inject code into the otherwise automated
process. So I'd rather treat existing "temps" as ordinary (non-temp)
targets.)
> Second, TEMPORARY is really designed to be used with the
> `updated` actions flag:
>
> actions piecemeal updated ar {
> ar rc $(<) $(>)
> }
>
> TEMPORARY x.o y.o z.o ;
> ar x.a : x.o y.o z.o ;
> RmTemps x.a : x.o y.o z.o ;
>
> In this case, rebuilding x.a because of one changed source,
> should not force the other object files to be created.
Are you saying that TEMPORARY isn't used anywhere else ? What about the
case of a library metatarget built from sources, where object files are
marked as TEMPORARY ?
In my original (faber) case, I build a "binary" B from a source B.c and
a library L, with a temporary object file B.o being removed after a
successful build. If I then touch the library sources L.c, the library
is rebuilt, and the binary relinked, but its object file B.o not being
recompiled (this is the symptom I narrowed down to the above minimal
test case), this fails.
Are you saying I shouldn't be using the TEMPORARY flag for B.o (et al.)
? How is b2 solving this case ?
Thanks,
Stefan
-- ...ich hab' noch einen Koffer in Berlin...
Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk