Boost logo

Boost-Build :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2002-09-10 08:28:10


David Abrahams wrote:
> From: "Vladimir Prus" <ghost_at_[hidden]>
>
>
>>Hi,
>>
>>a recent discussion with Markus Sch?pflin
>>(http://groups.yahoo.com/group/jamboost/message/1561)
>>ended with the conclusion that we need per-source requirements, like this
>>
>>exe a : a.cpp b.cpp/<pch>off my_project_pch ;
>>
>>Which will compile b.cpp without pch, but a.cpp with.
>
>
> I agree in principle, but I don't like the syntax much. It's too confusable
> with a path:
>
> exe a : a.cpp src/detail/b.cpp/<pch>off my_project_pch ;
>
> Doesn't that scare you a little?

Hmm... you've missed something and I've made some mistake. I propose syntax

exe a : a.cpp src/detail/b.cpp:<pch>off my_project_pch ;

However, we already have a syntax that you find confusing

exe a : a.cpp src/detail/somelib/<optimization>space ;

would explicitly select space-optimized version of somelib. The syntax
doesn't scares *me*. Anyway, there two cases of using requerements
together with sources, and we need separate syntaxes for both.
I currently propose "/" for selecting subvariant of dependency, and
":" for per-source requirements. Better suggestions are welcomed.

> Also, we probably ought to be thinking in terms of a future where users
> write pch=off instead of <pch>off, but that's a discussion for another
> time.

Do you plan to elimitate grist from user view of properties algotether.
That's fine idea.

>>I think it might be easy to implement, and it will also handle
>>"exported" requirements.
>
>
> Do you mean requirements intended for dependents of the target being built?

Yes.

>>Each virtual target will be assigned a set of "use requirements". They
>>will work in this way:
>>
>>
>>EXE <--------- a.obj <--------- a.cpp
>><---------- b.obj <--------- b.cpp (<pch>off)
>><---------- libboost_bgl (<include>/path/to/boost)
>>
>>Each generator first builds a dependecy graph. After that, it decides
>>wether to apply "use requirements". Any given
>>use requirement is applied if
>>1. There's at least one generator, used for building the dependency
>>graph, for which the requirement is relevant
>>2. The requirement was not applied previously.
>>
>>For example, generator for b.obj notices <pch>off requirement, which was
>>not yet applied and which is relevant.
>>So, it applies it to the action which builds b.obj from b.cpp. Later,
>>generator for EXE, notices that <pch>off was already
>>applied
>
>
> ?? To the exe ?? When was it applied there?

No, it was applied to obj<-cpp generator. That's the whole point: as
soon as use requirement made any effect on part of dependency graph,
it's not used anymore. <pch>off, specified for b.cpp, had effect on
b.obj construction, so it's not used after that.

Consider that you specify pch file as one of sources, in the same example.

EXE <--------- a.obj <--------- a.cpp
<---------- b.obj <--------- b.cpp (<pch>off)
<---------- libboost_bgl (<include>/path/to/boost)
<----------- my_pch (<pch>on)

That pch file will have <pch>on as use requirement. It will apply to all
obj<-cpp transformation, except for b.obj, because <pch>off has effect
only on b.obj (overriding settings that came from EXE generators). If
EXE generator cared for <pch>off here, you'd have two different
settings, and a conflicts.

> , so nothing is done about it. However, <include>/path/to/boost
>
>>was not yet applied and it relenant for obj<-cpp
>>generator, which was used to construct the graph for EXE. So, it is
>>applied to obj<-cpp actions.
>
>
> Could you write some pseudocode for this process? I don't think I get it
> yet.

rule generate ( .... )
{
g = <construct dependency graph>

self.relevant-properties = ....

for s in $(sources)
{
use-requirements += [ $(s).use-requirements ] ;
self.relevant-properties += [ $(s).relevant-properties ] ;
}

for u in $(use-requirements)
{
if $(u) in $(relevant-properties)
{
# Apply $(u) to actions in the dependency graph
}
}
self.use-requirements [ $(use-requirements) - $relevant-properties]

}

>>There's another interesting use case. BGL needs to compile the same file
>>with two different defines. I wish we could
>>do:
>>
>>lib libgraph : parser.y:<define>BGL_UNDIRECTED_PARSER
>>parser.y:<define>BGL_DIRECTED_PARSER ;
>
>
> Huh? Don't you need to specify different intermediate target names
> somewhere?

If you accept my proposal below, then no. Even if you don't accept it,
you can use some custom non-free property.

lib libgraph : parser.y:<bgl.parser-direction>u
parser.y:<bgl.parser-direction>d ;

>>This will work with the proposed scheme, except the we'll have two
>>imtermediate objects with different values of
>>free properties. Hey, why can't be support it? Simply: we can make free
>>properties added by use requirements special, and add them to target
>>path. This won't lead to much increase in path length, since such
>>properties are rare.
>>
>>Opinions?
>
>
> So when a library dependency adds #include paths, you plan to stick those
> in the target path? Sounds like a huge mistake to me...

Nope. Those include paths will be the same for all object, in 99.999% of
circumstances. Free properties will appear in path only when there are
two intermediate files (for the same subvariant of main target) with
different free properties.

- Volodya

 


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