Boost logo

Boost-Build :

From: David Abrahams (dave_at_[hidden])
Date: 2007-04-17 05:34:25

on Tue Apr 17 2007, Vladimir Prus <> wrote:

> consider this:
> lib a : a_msvc.cpp : <toolset>msvc <link>static ;
> lib a : a_gcc.cpp : <toolset>gcc ;
> What the user wants here?

Presumably the user wants the semantics that the system implements for
this case, or he would have written something else. There's certainly
no lack of clarity until you look at a particular build request, any
more than a pair of C++ function overloads are unclear until you look
at a particular invocation.

Today, Boost.Build treats this combination, **when combined with
_particular_ build requests**, as ambiguous. It's not considered
ambiguous when combined with other build requests.

Today's semantics are analogous to C++ treating the following as

    struct Base {};
    struct Derived : Base {};
    int f(Base*);
    int f(void*);

    Derived d;

    int x = f(&d); // <== here

Yes, a person designing C++ could say that it isn't clear which
overload the user wants, or he could design the overload resolution
rules so as to disambiguate more cases. In this case, C++ says that
the first overload is a better match based on more selective matching
criteria. I'm proposing a similar decision in Boost.Build.

> My opinion here is that it's bad design to have one syntactic
> element to be used both to affect selection of alternatives,
> and, once alternative is selected, to affect build properties.

It's only bad design if the two issues are unrelated, but they're not.
They're very commonly correlated, (as my proposal says, "one usually
wants a target to be built with properties that correspond to what the
user explicitly requested") and in fact the current design of
Boost.Build implicitly acknowledges that correlation -- just not as
fully as it could.

I'm not claiming that the correlation is absolute: there may be cases
when in fact making alternative selection choices based on build
requirements cannot produce the desired result (although so far,
AFAIK, we don't have a single user request for behaviors that can't be
achieved with my proposal). In that case I suggest you propose a way
to override that selection behavior (e.g. "when").

> With equal success, we can try to merge default build, requirements
> and usage requirements in one parameter.

That would only be true if they are all strongly correlated. But
they're not.

> I believe the fundamental thing about alternative selection is it
> can fail. For a trivial example, if we have alternatives for gcc
> and msvc, we don't want either to be silently selected when building
> with borland.

Why is that any worse than silently selecting a single target (with no
alternatives) whose requirements are <threading>multi when building
single-threaded? That is the current behavior.

> I don't think that toolset is the only special property. You might
> have hand-coded assembly files that must be selected depending on
> target architecture, or on compiler/architecture combination as
> well.
> Therefore, for each alternative we should have explicit list of properties
> that must be present in build request in order for that alternative to
> be selected. I propose an explicit syntax to do that:
> lib a : a.cpp : when <toolset>gcc ;
> lib a : a2.cpp : when <toolset>msvc ;
> The selection logic will be simple -- the properties in 'when' clause must
> be present in build request for the target, otherwise the alternative is
> not considered. If we end up with a single alternative, everything's OK.
> When more than one alternative is possible, we compare each pair
> possible alternatives. If "when" properties of one alternative are
> strict subset of "when" properties of the other alternative, the
> first alternative is discarded. For example:
> Alternative #1 : when <toolset>gcc
> Alternative #2 : when <toolset>gcc <link>static
> Alternative #3 : when <tooset>gcc <threading>multi ;
> If we're building with <toolset>gcc <link>static <threading>single,
> alternatives #1 and #2 are viable, and we select #2. If we're
> building with <toolset>gcc <link>static <threading>multi, all
> alternatives are viable, and we cannot select between #2 and #3,
> so it's ambiguity.
> Comments?

Well, I understand it, but that doesn't make it usable. My proposal
is concerned with making real use-cases work out.

I have two prebuilt libraries, one of which I need to be selected if
*any* of three properties is present in the explicit build request.
In my proposal, that is represented as:

  lib foo : : <name>foo_generic ;
  lib foo : : <name>foo_dbg <feature1>value1 <feature2>value2 <feature3>value3 ;

Can you please demonstrate the alternative declarations that would be
required to achieve the same result using your proposal?

Dave Abrahams
Boost Consulting
Don't Miss BoostCon 2007! ==>

Boost-Build list run by bdawes at, david.abrahams at, gregod at, cpdaniel at, john at