From: David Abrahams (dave_at_[hidden])
Date: 2003-03-24 21:00:51
Ali Azarbayejani <ali_at_[hidden]> writes:
> David Abrahams wrote:
>> >> It seems as though this could be expressed more simply like this:
>> >> lib b : b.cpp : : : <include>./include/b ;
>> >> lib a : a.cpp b : : : <include>./include/a ;
>> >> exe e : e.cpp a ;
>> > As written, this would mean that 'b' should be linked into 'a' --- which
>> > is something we don't support (and not sure we should).
>> Yeah, it's not consistently achievable across platforms. I think Ali
>> is suggesting that the lib rule give special meaning to libs that
>> appear in the list of sources for libs, though. IOW, it would
>> translate the 2nd line into
>> lib a : a.cpp : : : <include>./include/a <library>b ;
>> I'm not sure I like that idea, but it's not completely unreasonable.
> Actually, I would propose this translation
> lib a : a.cpp : <uses>b : : <include>./include/a <library>b ;
Yes, of course.
> But to dis-ambiguate the multiple uses of <library> consider, for the
> purposes of illustration, a new feature <link-to> that represents the
> usual purpose of <library>, and have <library> represent only the
> higher-level purpose described above (i.e. shorthand for both <uses>
> and <link-to>).
> That is,
> <uses>X (a.k.a. <dependency>) means append the Usage-Req's of X to
> my Requirements (recursively) (as currently implemented for
> <link-to>X appearing in properties means X must be linked in when
> any linking takes place (as <library> is currently
> implemented when used in Usage-Req's of a lib or Req's of an
> <library>X now exclusively means shorthand for both Requirement
> <uses> and Usage Requirement <link-to> (as <library> is
> currently implemented as Requirement for "lib" target)
I understand that you're decomposing orthogonal concepts here. I like
that in principle, and it may be the right move for our
implementation, but I also feel fairly well convinced that most users
_should_ never have to know about these distinctions.
> lib b ;
> # Normally, how static or shared libraries depend on each other.
> # Note that using the low-level features <uses> and <link-to>
> # requires a redundant specification. Usually, even with many
> # template libraries, if you <uses>, you also <link-to>.
> lib a : a.cpp : <uses>b : : <link-to>b ;
I've been thinking that just to make the language nicer it should be
<use> instead of <uses>.
> # Shorthand for above (proposed)
> lib a : a.cpp b ;
> # Shorthand for above (proposed) (N.B. a client of lib "a" would
> # get <link-to>b; it wouldn't get <uses>b or <library>b...literally
> # shorthand for the above.)
> lib a : a.cpp : <library>b ;
Hmm, the way <library> in requirements expands to something which
includes a usage-requirement worries me a little now. Currently
there's no provision for this sort of cross-category composite feature
expansion. I begin to wonder if we shouldn't have a different way to
deal with usage requirements that puts them all in the requirements
<use>b <usage:link-to>b # **
> # If you wanted to have a statically-linked DLL, you would have to
> # do something like this. This would somehow have to interact with
> # the <link> feature. Note the difference.
> lib a : a.cpp : <uses>b <link-to>b ;
Which is the statically linked DLL (whatever that is!) in this case?
a or b?
> # If, e.g., b's headers are in a's public interface, you might do
> # the following to expose b's usage requirements. (Again, from a
> # purist SW architecture point of view, I always recommend against
> # this sort of sneaky thing...but it comes up and this is how to do
> # it.)
> lib a : a.cpp : <library>b : : <uses>b ;
If a and b have any templates or inline functions, it may not matter
whether b's headers are in a's public interface. <use>b might still
be imposed on whoever is using a.
Should there be some way for a to say that any usage requirements it
inherits get propagated on to its dependents?
> # These would be unusual, but illustrate what <library> in
> # usage-requirements means.
> lib a : a.cpp : : : <uses>b <link-to>b ; # client to lib a uses and links b
> lib a : a.cpp : : : <library>b ; # same as above
> # N.B. the second line would basically would pass on the <library>
> # property to the client of "a", which would then expand it to
> # Requirement <uses>b and ((for a "lib") Usage-Requirement <link-to>b
> # or (for a "exe") Requirement <link-to> b). Thus, functionally,
> # <library> only gets expanded when it is a Requirement.
Sneaky. This makes me think that (**) above was really on the right
> # Executables
> exe e : e.cpp : <link-to>b ; # e merely links to b
Explicitly and stubbornly ignoring b's usage requirements?
OK, but it's inadvisable, right?
> exe e : e.cpp : <uses>b <link-to>b ; # e directly uses b and links to b
> exe e : e.cpp b ; # same as above (uses and links)
> exe e : e.cpp : <library>b ; # same as above (uses and links)
I like these, especially the middle one.
>> Maybe I'm coming around to Ali's point: if whether you want
>> <library>somelib or <uses>somelib is determined entirely by the kind
>> of target being declared (lib or exe), we should collapse the
>> distinction in the feature names, and just give it different semantics
>> depending on context.
> My new <library> feature described above will achieve this for the
> normal cases. But you may want to keep the lower-level <uses> and
> <link-to> properties for the various cases when normal semantics need
> to be overridden (e.g. statically linking a DLL, or passing through
> usage requirements for a variety of possible reasons).
As I said, I have some concerns about <library> and the cross-category
expansion. In any case, the orthogonal <use> and <link-to> features
make sense to me.
>> One other concern I have is the common need to repeat properties in
>> the requirements and usage-requirements sections, particularly some
>> defines and most includes. It would be nice to eliminate that
> The above proposal addresses some of that...at least you don't need to
> specify both <uses> and <link-to> most of the time.
That really doesn't help with either of the cases I mentioned, I
I'm thinking of:
lib x : x.cpp
: <include>./include <define>XSPOOF
: : <include>./include <define>XSPOOF ;
-- Dave Abrahams Boost Consulting www.boost-consulting.com
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