Boost logo

Boost-Build :

Subject: Re: [Boost-build] feature, properties, variants, and all the rest
From: Stefan Seefeld (stefan_at_[hidden])
Date: 2017-08-03 21:57:03


On 03.08.2017 17:38, Steven Watanabe via Boost-build wrote:
> AMDG
>
> On 08/03/2017 03:08 PM, Stefan Seefeld via Boost-build wrote:
>> On 03.08.2017 16:47, Steven Watanabe via Boost-build wrote:
>>> On 08/03/2017 02:11 PM, Stefan Seefeld via Boost-build wrote:
>>>> Yes, figured. Can you draw out the dependency graph in more detail (or
>>>> just the bits involved in making 'C') ? If I request `b2 C`, what are
>>>> the steps involved, leading up to some file
>>>> "bin/gcc-7.1.1/release/.../C.exe" being generated ? I expect something
>>>> like this:
>>>>
>>>> * C is declared in the Jamfile, as being depend on C-gen (a generator
>>>> rule that will actually instantiate some further dependency graph for C)
>>> I'm not quite sure what you mean by a generator rule.
>>> generators are based on target type. So with C as
>>> a typed-target{EXE}, we get:
>>>
>>> construct EXE from CPP:
>>> - composing generator gcc.link OBJ -> EXE
>>> (required properties <toolset>gcc-7.1.1) is viable
>>> - Need OBJ, trying to construct OBJ from CPP
>>> gcc.compile.c++ is viable
>> I was referring to the fact that, as you confirmed in a previous reply,
>> "building C means to generate the dependency graph [for C]", so I called
>> that step that does that the "generator rule".
>>
>> My question really was this: Once the Jamfile is read in, the target "C"
>> has to be registered, but the filename ".../C.exe" isn't, as it falls
>> out of the generation of the dependency graph, which will determine what
>> toolset to use, which in turn affects the qualified filename of C.exe.
> Yep.
>
>> Thus, I wondered how it is possible to submit to the engine a request to
>> build "C", and have .../C.exe being made in the process even though at
>> the time when the request is made nothing is known about it yet.
> I don't follow. When you build C, you have to specify
> the properties, which gives enough information to calculate
> the file path.

Consider again my earlier example, where the target "C" depends on some
config checks "A" and "B", during the update of which some properties
will be set that are used to build C.
I think the spelling was

exe C : C.cpp : [ check-target-builds B : <use>B ] ;

So, let's assume that one of the usage requirements of "B" affects the
choice of the toolset, or some other essential property that influences
the qualified filename .../C.exe.
My point simply was that, at the time `b2 C` is invoked, nothing is
known yet about .../C.exe. It's the generator action associated with
C-gen that will inject a new target for .../C.exe, and make it a
prerequisite of C to tell b2 to build that as part of building C.

>> I thus imagined that one way to implement this was by making C dependent
>> on C-gen, then let C-gen as it is being made inject other dependencies
>> for C, notably all those that are concerned with the compilation from
>> C.cpp into C.exe.
>>
>>>> * Thus, after reading the Jamfile, b2 does this:
>>>>
>>>> - considering C (to be built from C.cpp)
>>>> - building C-gen (as C's "static" prerequisite)
>>>> * this will determine g++-7.1.1 as the tool to build C.exe from
>>>> C.cpp via C.o
>>>> * thus, C.exe is injected as a new prerequisite target for C, C.o
>>>> as dependency for C.exe
>>>> - building C.o from C.cpp
>>>> - building C.exe from C.o
>>>> - building C (nothing left to do, it's just an alias for C.exe)
>>>>
>>>> Does this make sense, and more importantly, does it capture the logic in
>>>> b2 ? (By "Static prerequisite" above I'm referring to the fact that the
>>>> dependency from C to C-gen needs to be known before the engine is
>>>> started, as otherwise it wouldn't find any prerequisites for C at all,
>>>> and thus just make nothing in order for C to be considered up-to-date.)
>>>>
>>> It's no quite correct to say that C is an alias for
>>> C.exe. There are actually three levels of targets.
>>> - A main target (such as C) is what is defined in the Jamfile
>>> - A virtual target is an intermediate layer representing
>>> a specific file. There can be multiple virtual targets
>>> for the same file as long as only one is actualized.
>>> (This mainly exists to allow backtracking in generators.
>>> Unlike a Jam target, creating a virtual-target doesn't
>>> affect global state, so it's safe to create and discard
>>> virtual-targets.)
>>> - A Jam target is the thing that gets passed to the
>>> build engine for processing.
>>>
>>> main-target.construct(properties) returns a list of virtual targets.
>>> virtual-target.actualize() returns a Jam target.
>> OK. But given that at least in my earlier case with config checks
>> affecting the properties passed down to main-target.construct(),
> That's not quite correct. main-target.generate
> (I got the name wrong. The top-level interface
> that builds the dependency graph is called generate
> not construct.) processes conditional properties,
> including config checks.

That's exactly my point. main-target.generate would be invoked as part
of the "C-gen" update above (in my model), no ?
>> the
>> call to "main-target.construct" needs itself to happen in a rule that is
>> invoked by the engine, after the config checks have been run, no ? So
>> Your last statement above ("main-target.construct(properties) returns a
>> list of virtual targets. virtual-target.actualize() returns a Jam
>> target.") thus needs to be performed in chunks executed by the engine,
>> rather than while the Jamfile is being processed. Right ?
> There's one more rule:
> UPDATE_NOW $(targets) ;
> Calls into the engine to cause a list of Jam targets to
> be updated immediately. Config checks use this to
> update targets earlier than normal.

I know. But as far as I understand, this is only needed as the only way
to get back the status of the target (i.e., whether it was built
successfully or not).
My whole question gravitates around the entire build process (including
the injection of new intermediate targets) being done in a single stage,
rather than requiring multiple distinct "config; make; test" stages.

>> And so it sounds like this transformation from main target over virtual
>> targets to jam targets is the equivalent of my above workflow from C
>> over C-gen to C.exe. Correct ?
>>
> It's sort of similar, but a single virtual-target represents
> a specific file, not a group files.

Thanks,
        Stefan

>
> In Christ,
> Steven Watanabe
>
> _______________________________________________
> Unsubscribe & other changes: https://lists.boost.org/mailman/listinfo.cgi/boost-build

-- 
      ...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