Boost logo

Boost-Build :

Subject: Re: [Boost-build] feature, properties, variants, and all the rest
From: Stefan Seefeld (stefan_at_[hidden])
Date: 2017-07-28 20:22:42


On 28.07.2017 15:48, Steven Watanabe via Boost-build wrote:
> AMDG
>
> On 07/28/2017 12:59 PM, Stefan Seefeld via Boost-build wrote:
>> I'm actually thinking of cases where (assuming multiple passes) a single
>> conditional may yield different (mutually exclusive) results. Consider
>>
>> 1) if defined(A) define(B) else define(C)
>> 2) if not defined(B) define(A)
>>
> Do you have an actual case that looks like this,
> or is it purely theoretical?

It's purely theoretical. But as I'm reimplementing b2's feature /
property logic in Python, I need to know what kind of inputs to expect
and how to handle errors.
(But also if I simply wanted to contribute to b2's documentation, I'd
want to start with foundations such as what could be called "feature
algebra". There are a lot of grey areas that would become clear if there
was a specification not just for syntax but also semantics, rather than
the current documentation that works mostly just by example.)
>> for which the final state depends on whether you start the evaluation
>> loop with 1) or with 2). It seems impossible for b2 to flag this as
>> wrong, and it may even be right, as long as a specific order of
>> evaluation of the conditionals as guaranteed. But in the absence of that
>> order, it simply is undefined.
>>
> The order of evaluation is irrelevant, because
> the algorithm actually works like this:
>
> eval-conditions(initial, conditionals) {
> current = initial
> repeat(conditionals.size() + 1) {
> added = [eval-one(c, current) for c in conditionals]
> new-result = initial + added
> if current == new-result
> return new-result
> current = new-result
> }
> handle error
> }
>
> It evaluates all of the conditions independently
> in each iteration and combines the results with
> the original properties. (It's important to use the
> original properties rather than the previous iteration
> to guarantee that the result is consistent.)

Ah ! I think this is rather important (the behaviour, not the
implementation), and should be part of the documentation. Or perhaps it
is, and I just haven't found it ?
>> Of course, looking at a single conditional statement (as in your
>> original example), there always is an implied order. But in real-world
>> scenarios that may not be the case (if for example configure checks are
>> combined with multiple prerequisite targets that all contribute to the
>> final property-set for a given target.
>>
>> How would b2 handle this ?
>>
> If you start from no properties defined, then there
> is no way to satisfy these constraints:
>
> A -> (1) requires B
> A B -> B is present, so (2) shouldn't add A
> A C -> (1) requires B, not C
> A B C -> C is extraneous
> B -> (1) doesn't add B without A
> B C -> There is no reason for B
> nothing -> (2) should add A
> C -> (2) should add A

I don't understand the syntax you use here, and therefore the meaning.
What do you mean by "A -> (1) requires B" ?
If I follow your rule (about individual constraints being evaluated
individually in each iteration), I get this:

0. start with no properties defined
1. iteration: add C (from first condition), add A (from second condition)
2. iteration: keep C, A (from first iteration), add B (from first condition)

Have I misunderstood the algorithm ?

> Therefore, this is correctly an error.
> (Note that anything that contains B would
> be consistent if we allow properties to appear
> out of the blue, which we don't).

Can you elaborate on what you mean by "out of the blue", and thus what
is not allowed ?

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