|
Boost-Build : |
From: Vladimir Prus (ghost_at_[hidden])
Date: 2001-12-04 04:22:56
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.
I have thought a little more about this and have some observations. Surely,
if we allow project aliasing (or how to call this?), it should be usable
everywhere.
1. exe foo : foo.cpp <lib>/home/ghost/build/boost-cvs/pythong ;
won't work: how build system is to tell which part of the name denotes path
to the boost root, and which part denotes project alias under project root.
We'd need to explicitly declare all used projects:
project boost : /home/ghost/build/boost-cvs ;
This won't work, since "project" is supposed to take over responsibiity of
telling Jamfile location, which is now done by "subproject" rule (and in
Jambase, by "SubDir" rule).
We'd need something like:
external_project boost : /home/ghost/build/boost-cvs ;
2. Consider
project test/lib1 : src/lib1 ;
(in some other file)
project test/lib2 : src/lib2 ;
And, in src/lib1/Jamfile:
lib lib1 : lib1.cpp <lib>test/lib2 ;
And in some other project
exe foo : foo.cpp <lib>test/lib2 ;
Then, user:
- in src/lib1 says either
boost-build, or
build-build test/lib2
- tries to build the other project
In all those cases, *all* jamfiles need to be scanned, just to find out where
test/lib2 is located. I'd find this not very nice, but don't have a solution.
Probably, there should be some "project index", which will be automatically
generated? This might be related to "Configuration and Installation" proposal.
> > > > 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?
"any" = "all", sorry.
> > > > 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.
Okay for me.
> 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) ] ;
> }
"%" is "$" ?
>
> otherwise, Jam will complain about "independent targets" if you build
> something which depends on only one of the products of the rule.
Ah! So this is is how to suppress those warnings! Well, the original perfoce
docs would give no clue....
> 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) ] ;
> }
OK.
> > > 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.
Great, only I don't know how almost anything about JavaScript....
looking forward for the new feature.
> > > > 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)
OK.
- 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