Boost logo

Boost-Build :

Subject: Re: [Boost-build] feature, properties, variants, and all the rest
From: Stefan Seefeld (stefan_at_[hidden])
Date: 2016-12-23 21:55:28


On 23.12.2016 19:24, Steven Watanabe wrote:
> AMDG
>
> On 12/23/2016 02:56 PM, Stefan Seefeld wrote:
>> On 23.12.2016 16:39, Steven Watanabe wrote:
>>> On 12/23/2016 01:44 PM, Stefan Seefeld wrote:
>>>> On 23.12.2016 15:29, Steven Watanabe wrote:
>>>>> A composite feature contains other properties:
>>>>> Ex: <variant>release -> <optimization>on
>>>>> <debug-symbols>off <define>NDEBUG
>>>> So 'variant' is a composite feature whose constituent (sub-)features are
>>>> 'optimization' etc. ? So 'composite' is the parent of a 'subfeature' ?
>>> The term 'subfeature' means something different.
>>> <optimization> can be used independently
>>> from <variant>. <variant> just bundles them
>>> for convenience.
>> OK. Can you illustrate how subfeatures are used in practice ?
> I thought I did. The most common use for
> subfeatures is the version of a specific
> compiler.

That much I understood. What I don't understand is how subfeatures are
accessed and used within the build system.

To put this into a somewhat broader context: What I'd like to arrive at
is kind of a "property algebra", i.e. an understanding of the types,
values, and operations that are involved in dealing with properties in
b2. For avoidance of doubt: syntax is only marginally important in this
context, as I'm trying to express these operations in Python. I'd
therefore really like to capture this on a semantic / conceptual level.

>>> <snip>
>>> lib A : a.cpp ;
>>> exe B : A b.cpp : debug <define>XX ;
>>>
>>> $ b2 B release define=YY
>>>
>>> B is built with
>>> - <variant>debug (requirements override command line release)
>>> - <define>XX (target requirements)
>>> - <define>YY (command line free feature)
>>> A is built as a dependency of B and gets
>>> - <variant>debug (propagated from B)
>>> - <define>YY (command line free feature)
>> Great, thanks. So in the above 'debug' will override 'release'. How
>> would I express "only build B when 'debug' is requested", as opposed to
>> "override whatever the user asks for" ?
>>
> You have two choices:
> - Use a conditional like <variant>release:<build>no
> - Add a no-op alternative
>
> exe B : b.cpp : debug ;
> alias B ;
>
> In this case if <variant>debug is present,
> then the first alternative will be chosen.
> Otherwise, the second will be chosen.

Interesting. Thanks, that's useful.
>>> In general, b2 --debug-build will explain in
>>> detail which properties are used to build
>>> each target.
>> Thanks, I will try that.
>>>> And how are properties combined with conditions ?
>>> Conditional properties are evaluated when
>>> processing target requirements. The actual
>>> algorithm evaluates all conditionals repeatedly,
>>> until it reaches a fixed point.
>>>
>>> Ex:
>>>
>>> rule c ( properties * )
>>> {
>>> if <variant>debug in $(properties)
>>> { return <define>DEBUG }
>>> }
>>>
>>> Requirements:
>>> <toolset>msvc:<link>shared <link>shared:<variant>debug <conditional>@c
>> (Can you please spell out this line in normal prose ? What does
>> "<link>shared:" stand for (specifically, what's the meaning of the ':') ?)
> The property before the ':' is the condition. If
> those properties are present, then the properties
> after the ':' will be included.

Thanks.
>>> Initial properties:
>>> - <toolset>msvc
>>> Round 1:
>>> - <toolset>msvc <link>shared (Other conditionals are not satisfied)
>>> Round 2:
>>> - <toolset>msvc <link>shared <variant>debug
>>> Round 3:
>>> - <toolset>msvc <link>shared <variant>debug <define>DEBUG
>>> Round 4:
>>> - <toolset>msvc <link>shared <variant>debug <define>DEBUG
>>> (Identical to round 3, terminating the algorithm)
>> Thanks. To understand this I need to first understand the meaning of the
>> initial requirement.
> It's just the initial state when evaluating
> conditionals. It could be anything. If
> you start with <toolset>gcc instead, then
> none of the conditionals will match and the
> final result will be <toolset>gcc without
> any extra properties from the conditionals.

Excellent, I think I understand the above logic now.

I still have a few follow-up questions, though:

* how are properties merged / propagated ? For example, what operation
is responsible to merge "<include>foo" to an existing property set (and
where would a conflict be caught if instead I used "<link>wrong" or
"<link>static <link>shared" or somesuch ?

* OK, I think this is enough for now, so I'll try to implement /
document what I understand so far. :-)

Thanks so much for your help, that's much appreciated !

        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