Boost logo

Boost-Build :

Subject: Re: [Boost-build] Interface for configuration framework
From: Vladimir Prus (ghost_at_[hidden])
Date: 2010-03-18 06:05:38


On Thursday 18 March 2010 12:28:23 Johan Nilsson wrote:

> Vladimir Prus wrote:
> > Folks,
> >
> > now that we've more or less decided how named parameters should look,
> > then
> > next question is how the interface for configuration framework should
> > work.
> > To remind, the goal is to perform various checks of environment, and
> > decide what should be built and how based on that -- and, importantly,
> > have a simple and consistent interface for that.
> >
> > Here's how a zeroeth approximation look like:
> >
> > exe long_double_check : has_long_long.cpp ;
> >
> > lib boost_math_tr1l : ...sources... :
> > [ check-target-builds long_double_check : : <build>no ] ;
> >
> > The 'check-target-builds' thing takes three parameters -- target id,
> > "true-properties" and "false-properties". When boost_math_tr1l
> > metarget
> > is generated, the long_double_check will be also generated and
> > immediately
> > built. If the built is successfull, then 'true-properties' will be
> > added
> > to build properties for boost_math_tr1l -- and 'false-properties' will
> > be added otherwise. So, the above code has the effect of skipping
> > boost_math_tr1l is the long_double_check target fails to build.
>
> The above worries me a bit.
>
> I almost exclusively build with "-q" to force immediate build cancellation
> on failure - that would mean that if long_double_check fails to build I
> wouldn't get any further at all, with any "later" target. Unless the
> check-target-builds somehow marks the "long_double_check" metatarget as
> "nocare" or whatever?

The trick here is that check test target is build in a special way.
Because the outcome of its build should affect how other targets are *generated*,
including whether any real targets are generated for them at all, it necessary
has to be fully build before the "regular" build process starts. For that
end a special builtin, called UPDATE_NOW was introduced, and I think -q
will stop the build done inside UPDATE_NOW, but will affect the 'main' build.

> > For avoidance of doubt -- this actually already works now. Contrary
> > to what I have though before, it's not even a big change.
>
> Sounds promising.
>
> > This example illustates something that I think is an important point
> >
> > However, this interface does not make it easy to emit sensible
> > messages.
> > It would like to see this when building:
> >
> > Performing configuration checks
> >
> > - long double : no
> >
> > Component summary
> >
> > - math : building
> > long long libraries skipped
> >
> >
> > And for that to work, we need to specify more detail, e.g:
> >
> > check-exe long_double_check "long double" : has_long_long.cpp ;
> >
> > lib boost_math_tr1l : ...sources... :
> > [ check-target-builds long_double_check :
> > : <build>no <message>"long long libraries skipped"
> > <component>math ] ;
> >
> > Does this seem passable? I think that adding 'human name' to
> > long_double_check target is not an issue, but the check-target-builds
> > interface makes me nervous.
>
> It doesn't look very obvious and is more verbose than desired, IMHO. Just to
> make things worse I started playing around a bit with a more "familiar"
> interface (probably a couple of syntax errors around here):
>
> ---
>
> probe-target long_double_check
> : sources
> has_long_long.cpp
>
> # We should really have something called "attributes" or "properties" -
> # labelling the below properties "requirements" doesn't feel quite right
> ...
>
> : requirements
> <type>exe
> <displayname>"long double"
> ;
>
> lib boost_math_tr1l
> : ...sources...
> : requirements
> <target-builds>long_double_check/<component>math/<message-fail>"long
> long libraries skipped"
> ;

I am not sure what I think about this approach. It introduces yet another
mini-language, which is probably hard to extend should we need so, while
a function can get a new parameter relatively painlessy

>
> ---
> or:
> ---
>
> [snip definition of long_double_check]
>
> alias long_double_check_for_math
> : long_double_check
> : requirements
> <component>math
> <message-fail>"long long libraries skipped" ;
>
> lib boost_math_tr1l
> : ...sources...
> : requirements
> <target-builds>long_double_check_for_math
> ;

This means you need quite considerable code for each component/target
that is checking for a given property.

> which might enable conditional stuff such as:
> ---
>
> alias long_double_check_for_math :
> long_double_check
> : requirements
> <component>math
> <message-fail>"using emulated long long libraries"
> <message-ok>"using native long long libraries"
> ;
>
> lib boost_math_tr1l
> : ...sources...
> : requirements
> <target-builds>long_double_check_for_math:<library>native_long_double
> <target-builds-not>long_double_check_for_math:<library>emulated_long_double
> ;

Well, this is already possible in my proposal, with:

        [ check-target-builds long_double_check : <library>native_long_double : <library>emulated_long_double ]

> (yes, there are details to be fleshed out)
>
> > I guess that <component> can be a requirements in Boost.Math Jamfile,
> > so that
> > it's not repeated for every target that might need configure checks,
> > leading to:
> >
> > lib boost_math_tr1l : ...sources... :
> > [ check-target-builds long_double_check :
> > : <build>no <message>"long long libraries skipped" ] ;
> >
> > Also, it might be good to provide a less generic mechanism for
> > skipping a
> > target, for example:
> >
> > lib boost_math_tr1l : ...sources... :
> > [ demand-target-builds long_double_check : "long long libraries
> > are skipped" ] ;
> >
> > How does that look? Again, it assumes <component>math is in
> > Boost.Math requirements.
>
> The latter, simple, case looks ok. I agree with Spencer's comment about
> using "require" instead of "demand", though.

I'm a bit concerned about using 'require' naming for anything that is part
of "requirements" -- sounds like double "require" qualifier.

> > Another question is about naming. I assume the most common checks
> > will be 'does this target builds' and 'is 3rd party library XXX
> > available'. And there are two variants for each check -- one were you
> > can specify true-properties and false-properties, and one that just
> > skips a target. So far, I propose this naming:
> >
> > check-target-builds <target> : <true-properties> : <false-properties>
> > ; demand-target-builds <target> : message ;
> >
> > check-module <module-name> : <true-properties> :
> > <false-properties> ; demand-module <module-name> : message ;
> >
> > Does this naming sufficiently reflects the differences in semantics?
>
> As above - "require" fits better that "demand". Also, just to add some
> alternatives:
>
> check-target-builds => target-builds
> check-module => module-exists

This looses the semantic bit of "we're checking". "target-builds" sounds like
a statement. Hmm, I wonder whether "if-builds" is a better name, for it
more directly reflects what is happening.

Thanks,

--
Vladimir Prus
http://vladimir_prus.blogspot.com
Boost.Build: http://boost.org/boost-build2

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