Boost logo

Boost-Build :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2003-10-20 00:29:16


David Abrahams wrote:

> > I'd appreciate all comments on this document.
>
> I got lost trying to read the table. I don't understand the meaning
> of the row and column headings.

I've added the following to the document:
The header of the table contains three linking options for the "b" library.
The "B creates" row explains which targets are generated by "b" when those
linking options are used. Finally, three remaining rows list linking options
for the "a" library and tell what "a" does with the targets produced by "b".

Did this clarify anything?

Modified document is attached.

- Volodya
 --Boundary-00=_sK3k/78Gqps998q Content-Type: text/html;
charset="iso-8859-1";
name="linking.html"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment;
filename="linking.html"

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
<TITLE></TITLE>
<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.0 (Linux)">
<META NAME="AUTHOR" CONTENT="Vladimir Prus">
<META NAME="CREATED" CONTENT="20031015;15444000">
<META NAME="CHANGEDBY" CONTENT="Vladimir Prus">
<META NAME="CHANGED" CONTENT="20031020;9264200">
<STYLE>
<!--
@page { size: 8.27in 11.69in }
P.text-body-indent { margin-left: 0.2in }
-->
</STYLE>
</HEAD>
<BODY LANG="en-US" DIR="LTR">
<H1>Improved library linking mechanism</H1>
<H2>Motivation</H2>
<P>When V2 first got the &lt;library&gt; feature, it was a good idea.
Together with usage requirements is allowed to link to a library
without bothering about transitive dependency on other libraries,
which must be linked as well. Unfortunately, the current model has a
couple of drawbacks:</P>
<UL>
<LI><P>it requires more typing than necessary</P>
<LI><P>it does not allow to directly link one library to another
one, for shared linking, and yet doing something sensible for static
linking.</P>
</UL>
<P>This document discusses what can be improved and proposes a
solution which can be implemented with little effort.</P>
<H2>Overview</H2>
<P>Assume executable “m” uses library “a”, and that library
uses another library, “b”. Naturally, the code of “b” should
be somehow available when “m” is run. There are two different
ways how we can achieve this:</P>
<UL>
<LI><P>Direct linking means that “a” library contains reference
to library “b”. On common toolsets, it's only possible is “a”
is a shared library. In this case, “b” will be automatically
found at runtime. The problem with this solution is that it will
just break for static build.</P>
<LI><P>Bubble-up linking meands that “a” does not contain a
reference to “b”. However, when the library is build,
Boost.Build is told about dependency on “b”, and “b” will be
automatically linked to “m”. The problem with this solution, as
described in docs, is that it's pretty verbose. For our example, the
declaration of “a” might look like:</P>
</UL>
<P CLASS="text-body-indent">lib a : a.cpp : &lt;use&gt;b : :
&lt;library&gt;b ;</P>
<P STYLE="margin-bottom: 0in">The duplication of “b” is not nice.
</P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<H2>Proposal</H2>
<P>It was proposed by Ali, IIRC, that putting library in sources of
other library does the right thing: use direct linking if the library
is build as shared, and use bubble-up if library is linked as static.
Later, Christopher Currie noted that for static linking, libraries in
sources of other libraries are passed through by the current code,
which opens an easy path for implementation.</P>
<P>Accordingly, it's proposed that dependency from one library to
another can be expressed in two ways:</P>
<UL>
<LI><P>Automatic: “lib a : a.cpp b ;”. When building with
&lt;link&gt;shared, direct linking is used. Otherwise, “b” is
returned together with targets created for “a” and this will be
effectively the same as bubble-up linking.</P>
<LI><P>Bubble-up: “lib a : a.cpp : &lt;use&gt;b : : &lt;library&gt;b
;”. For both static and shared linking, “b” is not linked it
but is returned as usage-requirement.</P>
</UL>
<P>Let's consider interactions between two libraries “a” and “b”,
where “a” depends on “b” and “b” might depend on other
libraries. The header of the table contains three linking options for
the “b” library. The “B creates” row explains which targets
are generated by “b” when those linking options are used.
Finally, three remaining rows list linking options for the “a”
library and tell what “a” does with the targets produced by “b”.</P>
<TABLE WIDTH=100% BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=3>
<COL WIDTH=64*>
<COL WIDTH=64*>
<COL WIDTH=64*>
<COL WIDTH=64*>
<THEAD>
<TR VALIGN=TOP>
<TH WIDTH=25%>
<P><BR>
</P>
</TH>
<TH WIDTH=25%>
<P>B: automatic/static</P>
</TH>
<TH WIDTH=25%>
<P>B: automatic/shared</P>
<P><BR>
</P>
</TH>
<TH WIDTH=25%>
<P>B: bubble up</P>
</TH>
</TR>
</THEAD>
<TBODY>
<TR VALIGN=TOP>
<TH WIDTH=25%>
<P>B creates:</P>
</TH>
<TD WIDTH=25%>
<P>“b” target and target for “b” dependendies.</P>
</TD>
<TD WIDTH=25%>
<P>A single target for “b”</P>
</TD>
<TD WIDTH=25%>
<P>A single target for “b” and &lt;library&gt; usage
requirements</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TH WIDTH=25%>
<P>A: automatic/static</P>
</TH>
<TD WIDTH=25%>
<P>Targets are returned together with the target for “a”</P>
</TD>
<TD WIDTH=25%>
<P>Target is returned together with the target for “a”</P>
</TD>
<TD WIDTH=25%>
<P>Target for “b” and targets in usage requirements are
returned.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TH WIDTH=25%>
<P>A: automatic/shared</P>
</TH>
<TD WIDTH=25%>
<P>All targets are directly linked</P>
</TD>
<TD WIDTH=25%>
<P>The target is directly linked.</P>
</TD>
<TD WIDTH=25%>
<P>The targets are directly linked.</P>
</TD>
</TR>
<TR VALIGN=TOP>
<TH WIDTH=25%>
<P>A: bubble up</P>
</TH>
<TD WIDTH=25%>
<P>Targets are returned in usage requirements.</P>
</TD>
<TD WIDTH=25%>
<P>Targets are returned in usage requirements.</P>
</TD>
<TD WIDTH=25%>
<P>Targets are returned in usage requirements.</P>
</TD>
</TR>
</TBODY>
</TABLE>
<P><BR><BR>
</P>
<P>To implement the above scheme we need two mechanism. One which
cause “b” target to be returned without processing when A is
linked statically, and the second to achieve the same processing for
&lt;library&gt; properties returned as usage requirements by “b”.</P>
<P STYLE="margin-bottom: 0in">The first mechanism is already in
place. If generator for static library sees another library as
source, that library is bypassed. The second mechanism requires that
&lt;library&gt; properties are treated as sources when building
library target. This can be archieved by tweaking the “construct”
method of the “lib-target-class” class.</P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<H2>Implementation</H2>
<P>The presented proposal requires two changes to the existing code:</P>
<UL>
<LI><P>The “construct” method of the “lib-target-class”
should find all &lt;library&gt; properties an add it to the list of
sources. After that, it can call inherited “construct”</P>
<LI><P>For “searched” libraries, current code contains a special
code. It look at all the &lt;library&gt; properties, finds which
refer to searched libraries and adds special &lt;find-shared-library&gt;
and &lt;find-static-library&gt; features, which are converted by
toolset into -l switches to the linker. When &lt;library&gt; is
converted into source, this logic should be adjusted and moved to
the “generated-targets” method of the “linking-generator”
class.</P>
</UL>
<HR>
<P ALIGN=RIGHT>Last modified: <SDFIELD TYPE=DOCINFO SUBTYPE=CHANGE FORMAT=DATE SDNUM="1033;1033;MMM D, YYYY">Oct 20, 2003</SDFIELD></P>
</BODY>
</HTML> --Boundary-00=_sK3k/78Gqps998q--


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