Boost logo

Boost-Build :

From: David Abrahams (david.abrahams_at_[hidden])
Date: 2002-04-18 08:25:25


----- Original Message -----
From: "Vladimir Prus" <ghost_at_[hidden]>

> I've comitted the most detailed description of milestone 1 under
new/m1.txt.
> Please take a look. In particular, it describes a set of tasks I think
> needed.

Here are my remarks (get ready):

> Milestone 1: Explicit transformations, subvariants and projects
>
> * User visibile features *
>
> ** The 'make' rule **
>
> Prototype:
>
> rule make ( target : sources * : generating-rule : requirements
* )
>
> Semantics:
>
> Specifies that whenever build request of 'target' is compatible
with
> 'requirements', the build actions can be generating by calling
> 'generating-rule', which should agree with this signature:
>

Where does the build request come from? Since you say "build request
'of' target" above I assume you are saying that there's already a
build request attached to it somehow.

> rule generating-rule ( target : sources * : property-set )
>
> Target and source names passed to the generating rule will be
> actual jam target names, with their dependencies and locations
> already set.

Is it important that dependencies and locations are already prepared?
If so, why?

> [I would like to retain the same interface for all rules that
> actually generate build actions. The current "flags" rule is nice
and
> should be carried over, but passing properties as well would make
> sure everything is possible.

I don't see a relationship to the flags rule, but I agree that the
generating rule should get build properties explicitly.

> It would be nice if closure could be specified as generating-rule.
> For example:
> make dummy.txt : : write_file "fobar" ;
> Maybe, this is too fancy.

No, I don't think it's too fancy at all. In fact, I'm certain it's
going to be important to be able to pass some data through to the
generating-rule.

> ]
>
> Names used in 'target' and 'sources' should strictly correspond to
> actual file names. (E.g. no guessing of ".exe")

Except, I suppose, for NOTFILE targets.

> Make rule would create main target, which can be referred from
other
> jamfiles. Main targets defined in the Jamfile in jam invocation
> dir will also be available as actual jam targets with plain names.

So, in order to produce the main target name, 'make' might strip the
suffix to produce a portable representation? Example, please!

> It is possible to use the 'make' rule several times with the same
> target. When deciding which path should be used when satisfying a
build
> request, preference is given to 'make' invocations with longer
list
> of requrements.

I don't understand this. Can you give an example, and can you explain
why you think this is a good idea?

> [if we want to allow mutually exclusive requirements, we might
want
> in addition to <optimization>off allow <optimization>!off. For
more conrtived
> requirements, it probably makes sense to use executed features.
> All this is a way too complicated for the first milestone.
> ]

Needs clarification, still.

> All properties will be considered relevant for the generating rule
for
> the purpose of computing subvariant identifier.

Now there's a slight contradiction. If you have to compute a
subvariant identifier, then you aren't starting with a true Jam target
name, because the target will have to acquire some grist to identify
the subvariant.

> Subvariant targets will be located under:
> $(jamfile-dir)/bin/main_target_name/$(subvariant-path)

I presume jamfile-dir/subvariant-path aren't actually meant to be
variables

> Make rule does not care for project requirements.
>
> Other targets may be referred using "@"-notation:
> [project-id] "@" path-in-project / target /
[additional-properties]
>
> [should we allow to refer to targets in the same jamfile using
> simple name?]

Yes; why not? Maybe we could leave that out of the first milestone,
though.

> When selecting which subvariant should be used when building main
target with
> some properties, the following mechanism is used:
>
> additional-properties are added to build properties for the
main
> target. Propagated targets are added to the result.
> The used main target is asked to produce an subvariant
> target with the resulting properties.
>
> [propagated and exported features are not handled for now]
>
> It should be possible to use targets from other projects (bad
word!) --
> i.e. which has other project-root.
>
> * Tasks *
>
> ** Finish initialization and its intraction with the 'project' module
**
"interaction"----------------------^^^^^^^^^^

>
> - The initialization code should use 'site.jam' and 'user.jam'
> (This would allow us to easily define toolsets for testing)
> - It should also take BUILD/TOOLSET and perform build request
> expansion.
> - It should call 'generate' on the abstract target which
corresponds
> to the project in Jam invocation dir.
>
> ** Implement notion of compatible and incompatible property sets **
>
> - Rountine apply-requirements ( build-request : requirements )

"Rountine" is not a word I know. Possibly you meant "Routine"? Anyway,
what's wrong with "rule"?

> Returns the property set that should be used for building
> a target with 'requirements' given the 'build-request'.
> Return empty string when 'requirements' cannot be satisfied.
> (Should some explanation be returned in this case?)

Yes, definitely. Otherwise, it will be hard for people to understand
why targets are skipped.

>
> - Rountine compose-requirements ( requirements1 : requirements2 )

> Returns a requirements set which is satisfied iff both
> 'requirements1' and 'requirements2' are satisfied. Returns
> an empty string otherwise.
> (Seems like does exactly the same as
> apply-requirements. However, it's better to have another
> name, to avoid confusion)

I think it's not the same. I think the build request is a "soft"
property set. Some elements of the request may be ignored or modified
according to the target requirements. However, I wonder about the need
for compose-requirements. Why not just dump the requirements together
as in $(requirements1) $(requirements2)?

> - A mechanism for specifying incompatible property sets.
> - at first stage it would suffice to declare some features
> as 'stict' -- targets with different values of such features
"strict"-------^^^^^
> cannot be linked together under no circumstances.
> Addition for feature.jam?

I think we need at least the expressivity of the current features.jam
gLINK_COMPATIBLE variable. If a feature appears in gLINK_COMPATIBLE,
all of its values are link-compatible with one another. If a property
appears there, it is compatible with all other properties having the
same feature.

> - later we might want to implement something more elaborate
>
> Notes:
> 1. I don't see any possibility of link-incompatibility
> which involves two features.

I do. Many compilers have an implicit relationship between RTTI and
EH, so that you can't compile with EH but without RTTI. It's a bit of
an edge case, but I'm sure there are others. Note however that this
incompatibility is toolset-specific.

> 2. Another possibility is to specify which features are
> compatible. But I belive that number of truly
> incompatible features is low, and explicitly writing
> down all compatible combinations will be harder.

I agree. I think it makes sense to write down which properties are
link-compatible with one another, as in gLINK_COMPATIBLE, but (if we
need to specify this at all) to write down which features are NOT
compatible with one-another. Put simply, there should be sensible
defaults: the default for features is that they are link-compatible
with one-another.

> 3. Can we need different 'link-compatibilities'? IOW, is
> it possible to have some different relation between
> ingridients for a target than 'linked-in'?

Good question, though I'd phrase it differently. What
link-compatibility is actually expressing is whether target A can be
used as a source for target B. How this question is answered might
depend on the types of A and B, and the process used to build A. For
now, though, let's not generalize this notion.

> ** Some property utilities **
>
> - Routine add-properties ( property1 : property2 )
> Returns a property set where value for each feature is looked
up
> first in property2 and only then in property1.
> It is assumed that property{1,2} do not contain composite
properties.

I can't envision a use for this one. Probably it's OK to write down
low-level components at this stage if you can really see how they fit
into the big picture, but you must describe how they fit or they are
just a distraction.

> - Routine subvariant-dir ( property-set )
> Returns a subvariant-dir. Elements of the dir should
correspond
> to feature description if feature.jam.

Relative to which directory?

Note that I want to make a small change to the way subvariant
directories are calculated. Namely, if <feature>value appears in the
requirements for a target, feature-variant shouldn't appear in the
subvariant path. It's a small difference but it would help to cut down
on the length of these paths.

> ** Project-id enhancement **
>
> It should be possible to use the 'project' rule to forward-declare
project,
> i.e. to associate project id with location, but give no
information.
> This is needed to that project-root.jam could declare all
project-id,
> and client won't be required to include all the Jamfiles.

I think I understand you, but examples are needed, please!

> ** Full implementation of abstract-target.generate **

Can you describe the signature for this rule? I don't see a class
"abstract-target" anywhere.

> It should
> - filter build request with requirements
> - select appropriate variants of used targets
> - construct a dependecy graph for target
> - return it.
>
> The depencency graph construction at this stage will be
implemented using
> call to construct.construct
> rule construct ( target : target-type : sources * :
properties )

Why pass the target-type? It seems to me that the abstract target
should know its target-type.

BTW, I'd like to have the definition of abstract, virtual, and real
targets written down somewhere.

> Main targets creates by the "make" rule will have target type
which
> processing will be hardcoded -- build dependency graph of depth 2
and
> return it.

I don't understand the above. Sorry that I need so much clarification.

> [it is possible that we generate more than one target because
> build actions create more than one. Handling of this is specified
> in architecture.html and should be implemented.]

That document describes a very un-hardcoded system, so I can't resolve
this with the previous sentence.

> ** Other enhancements for abstract-target **
>
> Path features should be supported somehow.

I guess so!

 


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