Boost logo

Boost-Build :

From: David Abrahams (david.abrahams_at_[hidden])
Date: 2001-12-03 18:05:53


----- Original Message -----
From: "Vladimir Prus" <ghost_at_[hidden]>
To: <jamboost_at_[hidden]>
Sent: Monday, December 03, 2001 7:56 AM
Subject: Re: [jamboost] (sub)project handling

> David Abrahams wrote:

> > So, what about this?
> >
> > project boost/python # (sub)project target id
> >
> > : libs/python/build # optional path from project root
----------------------------------^^^^^^^^
> >
> > ;
> No objections. Would be reasonable to have shortcut form -- i.e. to make
the
> second argument optional, it which case value of the first argument is
used.

That was what I had in mind.

> > > 2. David has proposed that Jamfiles should be declarative: first some
> > > data
> >
> > is
> >
> > > gathered and only then build instructions are generated. Is this
> > > sufficient
> > > for all uses? What if somebody wants simply to define some targets?
> >
> > I don't understand the problem.
> The problems I see is that it:
> 1) Will defeat the aim of making Jamfiles declarative
> 2) Will cause building of extra targets when jam is invoked from subdir.
This
> happens i some target is explicitly added to "any" dependencies.

Sorry, what are "any" dependencies?

> > > Explicit target creation won't work with it, will it?
> >
> > I'm still not sure I see the problem.
> >
> > 1. Explicitly created targets will end up in the dependency graph, but
so
> > what?
> >
> > 2. If we provide new declarative target primitives, users can
"explicitly
> > create" a target declaratively, so that it interoperates with the rest
of
> > the system.
>
> Actually, you suggest to hide Jam's primities (DEPENDS &c) altogether.

They wouldn't be unavailable; just deprecated ;-)

> In
> fact, this might be a good idea, as it's already impossible to work with
jam
> without knowning something about Jambase, so plain primitives level is not
> usefull alone. Is making new declarative target primities what you'd
really
> like?

Yes. For example, there's a pattern you *need* to follow if you have an
action which generates multiple targets at once:

for local t in $(<)
{
INCLUDES $(t) : [ set.difference $(<) : %(t) ] ;
}

otherwise, Jam will complain about "independent targets" if you build
something which depends on only one of the products of the rule.

why should we write that more than once? I can't see a reason. So for
example, one primitive might be:

# build targets from sources via the rule named by action.
rule construct ( targets + : sources * : action )
{
local head = ;
local tail = $(targets) ;
while $(tail)
{
INCLUDES $(tail[1]) : $(head) $(tail[2-]) ;
head += $(tail[1]) ;
tail = $(tail[2-]) ;
}
return [ $(action) $(targets) : $(sources) ] ;
}

> > Lists of strings ;-)
> > Seriously, though: let's look at what we need.
> >
> > Each Jamfile will be loaded as a distinct module. Target declarations
can
> > be stored in module local variables. We'll need:
> >
> > 1. A list of the target names declared in the Jamfile. That's easy; we
can
> > store that in a list of strings.
> >
> > 2. For each target, its sources, dependencies, requirements, and default
> > build. Also relatively easy: we can store each one in a variable whose
name
> > is based on the target name. For example:
> >
> > rule declare-target ( name type levels ? : sources * : dependencies * :
> > requirements * : default-build * )
> > {
> > levels ?= 2 ;
> > local jamfile = [ CALLER_MODULE $(levels) ] ;
> > module $(jamfile)
> > {
> > module local __targets__ ;
> > # need an error check here
> > __targets__ += $(name) ;
> > $(name).__sources__ = $(sources) ;
> > $(name).__dependencies__ = $(dependencies) ;
> > $(name).__requirements__ = $(requirements) ;
> > $(name).__default-build__ = $(default-build) ;
> > }
> > }
> Okay. For me it looks like the first thing to be written now... Just in
case
> I'll have spare time, isn't this already implemented?

Not yet. Actually, I have an idea of how to implement a prototype-based
object/inheritance system (a la JavaScript and probably some earlier
languages) on top of the module facility. I'll try to slap that together; I
think it will help with this problem.

> > > 4. (completely unrelated to the subject)
> > > Is there a way for a module to define rules at global scope? To
declare
> >
> > rule
> >
> > > using dynamically computed name? I was thinking about a rule like
> > > "declare-main-type". E.g.
> > > declare-main-type exe ......
> > > could create global rule called exe.
> >
> > Not exactly, but you can declare a rule and import it into any module
using
> > a dynamically computed name.
> Can it be imported to the global namespace?

Sure:

local global-namespace = ;
local target-rule-names = $(source-rule-names) ;
IMPORT source-module : $(source-rule-names) : $(global-namespace) :
$(target-rule-names)
>

 


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