Boost logo

Boost-Build :

Subject: Re: [Boost-build] feature, properties, variants, and all the rest
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2017-08-05 23:13:53


AMDG

On 08/05/2017 04:27 PM, Stefan Seefeld via Boost-build wrote:
> On 08/05/2017 04:15 PM, Steven Watanabe via Boost-build wrote:
>>
>> <snip>
>> Why would you think that? I just stated that
>> the engine only gets involved when the Jam targets
>> are passed to it. (I'm considering the Jam interpreter
>> to be separate from the build engine here.)
>
> Ah, may be that's part of my misunderstanding. So let me outline my
> understanding of this. Please correct me as appropriate:
>
> The engine is a scheduler for actions needed to update targets. So it
> has a representation of targets to indicate whether they need updating,
> are up to date, or are somewhere in between. Actions are written in Jam,
> and are parsed into some IR by a Jam parser when the Jamfile is read in.
> At some point these actions are translated (by the Jam interpreter) into
> a sequence of commands that are run sequentially (by the scheduler).
>

  That's basically correct, except that you should
think of Jam as something like a general purpose
programming language. The Jam parser, per se, doesn't
create the IR. It just executes code. The IR is
built by various rules defined by Boost.Build that
are called from the Jamfile.

> (What I still don't quite understand is the relationship between rules
> and actions.)
>

  This is basically about low level Jam syntax. Do
you really care about it or are you asking about something
different?
  A rule is basically a function. You can call it with
arguments, it can have various side-effects, and you
get back a result. An action creates a node in the
dependency graph.
When you call
compile.c++ x.o : x.cpp ;
it appends itself to the list of updating actions for x.o.
  Rules and actions are called with the same syntax. In
addition, if a rule and action have the same name, then
calling it will do both (This is typically used to allow
a rule to set some variables that are needed by the
corresponding action).

>
> <snip>
> Ah, so it now looks like this happens after the Jamfile has been parsed,
> but before the engine is "started", and thus, before the config checks
> are run. (Thus the question: how can the config check results be used,
> if the lowering happens before they are known ?)
>

  When you run a config check, the subgraph corresponding
to the config check is immediately lowered and executed
(outside the normal order of execution). This isn't really
the best abstraction, but it allowed us to patch support
for config checks into a system that originally had no
support for them at all.
  You can think of Boost.Build as using a pull model for
config checks, while you're using something more like a
push model.

>
>> <snip>
>> Because the dependencies are not explicitly modeled,
>> but are rather a result of the ordering imposed by
>> executing code it's impossible to schedule the
>> tasks in any way other than running them as they
>> are encountered.
>
> Ah. Yeah, that is a problem. But I suppose there would be ways to
> translate the "<use>A" expression into an additional dependency to A,
> thus forcing a particular order of execution ?
>

  That's too late. By the time <use>A is applied, the configure
check has already been processed. All that the Boost.Build core
sees for a configure check is an opaque
<conditional>@some-internal-function-defined-by-check-target-builds

In Christ,
Steven Watanabe


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