Boost logo

Boost-Build :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2004-03-22 03:29:11


Hello,
for quite some time we had a couple of buggy corner cases in the algorithm
which computes build properties for a target

1. If a composite property had default value, then default value was added,
but not expanded.

2. Subfeatures in requirements were not expanded, so something like

<toolset>msvc-6

did not work quite right.

So, I've decided to revise the algorithm a bit. The new version was just
comitted, which fixes the above bugs. It also makes requirements like:

<toolset>gcc:<variant>release <variant>release:<define>FOO

work in an intuitive way: i.e. FOO is defined.

This version is not necessary final. I attach description of the algorithm
(which will be eventually added to docs) and will appreciate any comments.
Of course, if the change breaks something or inpacts performance, I'd like to
know as well.

Thanks in advance,
Volodya

 --Boundary-00=_XPqXA9IplWmQDI8 Content-Type: text/plain;
charset="us-ascii";
name="properties.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="properties.txt"

This document describes the how properties used to build a targets are
determined.

For a while, we're concerned about building a single alternative of a main
target. We don't care how alternative is selected, nor we care about
default-build attribute.

This leaves us with two inputs: build requests and requirements. From
that we need to compute build request that should be passed to dependencies,
and build properties that should be used when building the target.

The rules which relate output with input are given below. They make use
of a third intermediate "common properties", from are computed from input
data. After that, two simple rules are used:

1. Build requests for dependencies contains all propagated properties from common
properties.

2. Build properties for the target has all properties from common properties,
as well as all usage requirements propagated from dependencies.

Common properties are determined by the following rules.

1. Non-free feature can have only one value

2. A non-conditional property in requirement in always present in
common properties.

3. A property in build request is present in common properties, unless (2)
tells otherwise.

4. If either build request, or requirements (non-conditional or conditional)
include a expandable property (either composite, or property with
specified subfeature value), the behaviour is equvivalent to explicitly
adding all expanded properties to build request or requirements.

5. If requirements include conditional property, and condiiton of this
property is true in context of common properties, then the conditional
property should be in common properties as well.

6. If no value for a property is given by other rules here, it has default
value if common properties.

The primary diffculty in implementing those rules is conditional properties.
If we've changed a property as result of evaluating one element of
conditional requirements, that can change other conditions and require to add
more elements. For example:

<toolset>gcc:<variant>release <variant>release:<define>FOO

Here, after evaluating first element we add <variant>release, which then
should be used when evaluating second elements. Also note that elements
might come in reserse order.

To handle this situation we need to repeatedly evaluate conditionals, until
results of evaluation stabilize.

Algorithm
---------

Basic ideas behind the algorithm are:

To satisfy rule (4), we expand composites/subfeatures whenever we add a new
property.

To satisfy rule (6), we add default values in the very start of the
algorithm. If requirements ask for a different value of a feature, we change
the value.

Conditionals are evaluated repeatedly untill process stabilizes. To avoid
infinite looping, the number of interation is limited by the number of
conditional properties. This allows dependencies between individual
conditional properties (like shown above) to propagate via all the properties,
if that's needed.

The algorithm itself in in 'targets.common-properties' and
'targets.common-properties2' rules.

Additional notes:

1. We can't really expand initial build request and then never call
'expand' on build request. The problem is that a composite property
exansion can include non-propagated properties (e.g. free, which are
never propagated). So, when building dependencies we'll forget those
non-propagated properties.

One alternative is additionally call 'expand' when building dependencies.
Other alternative is to call expand right at the start of
'main-target.generate'.

 --Boundary-00=_XPqXA9IplWmQDI8--


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