Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/more/separate_compilation.html @ 37

Last change on this file since 37 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 20.8 KB
Line 
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<html>
3   <head>
4      <title>Guidelines for Authors of Boost Libraries Containing Separate Source</title>
5      <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
6      <LINK href="../boost.css" type="text/css" rel="stylesheet"></head>
7   <body>
8      <TABLE summary="Page header" id="Table1" cellSpacing="1" cellPadding="1" width="100%" border="0">
9         <TR>
10            <td vAlign="top" width="300">
11               <h3><A href="../index.htm"><IMG height="86" alt="C++ Boost" src="../boost.png" width="277" border="0"></A></h3>
12            </td>
13            <TD width="353">
14               <H1 align="center">Guidelines for Authors of Boost Libraries Containing Separate
15                  Source</H1>
16            </TD>
17         </TR>
18      </TABLE>
19      <BR>
20      <HR>
21      <P>These guidelines are designed for the authors of Boost libraries which have
22         separate source that need compiling in order to use the library. Throughout,
23         this guide refers to a fictitious "whatever" library, so replace all
24         occurrences of "whatever" or "WHATEVER" with your own library's name when
25         copying the examples.</P>
26      <H2>Contents</H2>
27      <dl class="index">
28         <dt><A href="#source_changes">Changes Affecting Source Code</A>
29            <dd>
30               <dl class="index">
31                  <dt><A href="#abi">Preventing Compiler ABI Clashes</A> <DT><A href="#static_or_dynamic">Static
32                           or Dymanic Libraries</A>&nbsp; <dt><A href="#dlls">Supporting Windows Dll's</A> <dt>
33                              <a href="#auto-link">Automatic Library Selection and Linking with auto_link.hpp</a>
34                           </dt>
35               </dl>
36               <dt><A href="#build_changes">Changes Affecting the Build System</A>
37                  <dd>
38                     <dl class="index">
39                        <dt><A href="#jamfile">Creating the Library Jamfile</A> <dt><A href="#testing">Testing
40                                 Auto-linking</A> </dt>
41                     </dl>
42                     <dt><A href="#copyright">Copyright</A></dt>
43      </dl>
44      <h2><A name="source_changes"></A>Changes Affecting Source Code</h2>
45      <H3><A name="abi"></A>Preventing Compiler ABI Clashes</H3>
46      <P>There are some compilers (mostly Microsoft Windows compilers again!), which
47         feature a range of compiler switches that alter the ABI of C++ classes and
48         functions. By way of example, consider Borland's compiler which has the
49         following options:</P>
50      <PRE>-b    (on or off - effects enum sizes).
51-Vx   (on or off - empty members).
52-Ve   (on or off - empty base classes).
53-aX   (alignment - 5 options).
54-pX   (Calling convention - 4 options).
55-VmX  (member pointer size and layout - 5 options).
56-VC   (on or off, changes name mangling).
57-Vl   (on or off, changes struct layout).
58</PRE>
59      <P>These options are provided in addition to those affecting which runtime library
60         is used (more on which later); the total number of combinations of options can
61         be obtained by multiplying together the individual options above, so that gives
62         2*2*2*5*4*5*2*2 = 3200 combinations!
63      </P>
64      <P>The problem is that users often expect to be able to build the Boost libraries
65         and then just link to them and have everything just plain work, no matter what
66         their project settings are. Irrespective of whether this is a reasonable
67         expectation or not, without some means of managing this issue, the user may
68         well find that their program will experience strange and hard to track down
69         crashes at runtime unless the library they link to was built with the same
70         options as their project (changes to the default alignment setting are a prime
71         culprit). One way to manage this is with "prefix and suffix" headers: these
72         headers invoke compiler specific #pragma directives to instruct the compiler
73         that whatever code follows was built (or is to be built) with a specific set of
74         compiler ABI settings.</P>
75      <P>Boost.config provides the macro BOOST_HAS_ABI_HEADERS which is set whenever
76         there are prefix and suffix headers available for the compiler in use, typical
77         usage in a header like this:</P>
78      <PRE>#ifndef BOOST_WHATEVER_HPP
79#define BOOST_WHATEVER_HPP
80
81#include &lt;boost/config.hpp&gt;
82
83// this must occur after all of the includes and before any code appears:
84#ifdef BOOST_HAS_ABI_HEADERS
85#  include BOOST_ABI_PREFIX
86#endif
87//
88// this header declares one class, and one function by way of examples:
89//
90class whatever
91{
92   // details.
93};
94
95whatever get_whatever();
96
97// the suffix header occurs after all of our code:
98#ifdef BOOST_HAS_ABI_HEADERS
99#  include BOOST_ABI_SUFFIX
100#endif
101
102#endif
103</PRE>
104      <P>You can include this code in your library source files as well if you want,
105         although you probably shouldn't need to:&nbsp;&nbsp;</P>
106      <UL>
107         <LI>
108            If you <EM>don't</EM>
109         use these in the library source files (but do in your library's headers) and
110         the user attempts to compile the library source with a non-default ABI setting,
111         then they will get compiler errors if there are any conflicts.
112         <LI>
113            If you <EM>do </EM>include them in both the library's headers and the library
114            source files, then the code should always compile no matter what the compiler
115            settings used, although the result might not match what the user was expecting:
116            since we've forced the ABI back into default mode.</LI></UL>
117      <H4>Rationale:</H4>
118      <P>Without some means of managing this issue, users often report bugs along the
119         line of "Your silly library always crashes when I try and call it" and so on.
120         These issues can be extremely difficult and time consuming to track down, only
121         to discover in the end that it's a compiler setting that's changed the ABI of
122         the class and/or function types of the program compared to those in the
123         pre-compiled library. The use of prefix/suffix headers can minimize this
124         problem, although probably not remove it completely.</P>
125      <H5>Counter Argument #1:</H5>
126      <P>Trust the user, if they want 13-byte alignment (!) let them have it.</P>
127      <H5>Counter Argument #2:</H5>
128      <P>Prefix/suffix headers have a tendency to "spread" to other boost libraries -
129         for example if boost::shared_ptr&lt;&gt; forms part of your class's ABI, then
130         including prefix/suffix headers in your code will be of no use unless
131         shared_ptr.hpp also uses them. Authors of header-only boost libraries may not
132         be so keen on this solution - with some justification - since they don't face
133         the same problem.</P>
134      <H3><A name="static_or_dynamic"></A>Static or Dynamic Libraries</H3>
135      <P>When the users runtime is dynamically linked the Boost libraries can be built
136         either as dynamic libraries (.so's on Unix platforms, .dll's on Windows) or as
137         static libraries (.a's on Unix, .lib's on Windows).&nbsp; So we have a choice
138         as to which is supported by default:</P>
139      <UL>
140         <LI>
141         On Unix platforms it typically makes no difference to the code: the user just
142         selects in their makesfile which library they prefer to link to.
143         <LI>
144         On Windows platforms, the code has to be specially annotated to support DLL's,
145         so we need to pick one option as the default and one as an alternative.
146         <LI>
147            On Windows platforms, we can inject special code to automatically select which
148            library variant to link against: so again we need to decide which is to be the
149            default (see the section on auto-linking below).</LI></UL>
150      <P>The recomendation is to pick static linking by default.</P>
151      <H4>Rationale:</H4>
152      <P>There is no one policy that fits all here.
153      </P>
154      <P>The rationale for the current behaviour was inherited from Boost.Regex (and
155         it's ancestor regex++): this library&nbsp;originally used dynamic linking by
156         default whenever the runtime was dynamic. It's actually safer that way should
157         you be using regex from a dll for example. However,&nbsp;this
158         behavior&nbsp;brought a persistent stream of user complaints: mainly about
159         deployment, all asking if static linking could be the default. After&nbsp;regex
160         changed behavior the complaints stopped, and the author hasn't had one
161         complaint about static linking by default being the wrong choice.</P>
162      <P>Note that other libraries might need to make other choices: for example
163         libraries that are intended to be used to implement dll pluggin's would like
164         need to use dynamic linking in almost all cases.</P>
165      <H3>Supporting Windows Dll's</H3>
166      <p>On most Unix-like platforms no special annotations of source code are required
167         in order for that source to be compiled as a shared library because all
168         external symbols are exposed. However the majority of Windows compilers require
169         that symbols that are to be imported or exported from a dll, be prefixed with
170         __declspec(dllimport) or __declspec(dllexport). Without this mangling of source
171         code, it is not possible to correctly build shared libraries on Windows
172         (historical note - originally these declaration modifiers were required on
173         16-bit Windows where the memory layout for exported classes was different from
174         that of "local" classes - although this is no longer an issue, there is still
175         no way to instruct the linker to "export everything", it also remains to be
176         seen whether 64-bit Windows will resurrect the segmented architecture that led
177         to this problem in the first place. Note also that the mangled names of
178         exported symbols are different from non-exported ones, so __declspec(dllimport)
179         is required in order to link to code within a dll).</p>
180      <p>In order to support the building of shared libraries on MS Windows your code
181         will have to prefix all the symbols that your library exports with a macro
182         (lets call it BOOST_WHATEVER_DECL) that your library will define to expand to
183         either __declspec(dllexport) or __declspec(dllimport) or nothing, depending
184         upon how your library is being built or used. Typical usage would look like
185         this:</p>
186      <pre>#ifndef BOOST_WHATEVER_HPP
187#define BOOST_WHATEVER_HPP
188
189#include &lt;boost/config.hpp&gt;
190
191#ifdef BOOST_HAS_DECLSPEC // defined in config system
192// we need to import/export our code only if the user has specifically
193// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
194// libraries to be dynamically linked, or BOOST_WHATEVER_DYN_LINK
195// if they want just this one to be dynamically liked:
196#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_WHATEVER_DYN_LINK)
197// export if this is our own source, otherwise import:
198#ifdef BOOST_WHATEVER_SOURCE
199# define BOOST_WHATEVER_DECL __declspec(dllexport)
200#else
201# define BOOST_WHATEVER_DECL __declspec(dllimport)
202#endif  // BOOST_WHATEVER_SOURCE
203#endif  // DYN_LINK
204#endif  // BOOST_HAS_DECLSPEC
205//
206// if BOOST_WHATEVER_DECL isn't defined yet define it now:
207#ifndef BOOST_WHATEVER_DECL
208#define BOOST_WHATEVER_DECL
209#endif
210
211//
212// this header declares one class, and one function by way of examples:
213//
214class BOOST_WHATEVER_DECL whatever
215{
216   // details.
217};
218
219BOOST_WHATEVER_DECL whatever get_whatever();
220
221#endif
222</pre>
223      And then in the source code for this library one would use:
224      <pre> 
225//
226// define BOOST_WHATEVER SOURCE so that our library's
227// setup code knows that we are building the library (possibly exporting code),
228// rather than using it (possibly importing code):
229//
230#define BOOST_WHATEVER_SOURCE
231#include &lt;boost/whatever.hpp&gt; 
232
233// class members don't need any further annotation:
234whatever::whatever() { }
235// but functions do:
236BOOST_WHATEVER_DECL whatever get_whatever()
237{
238   return whatever();
239}
240</pre>
241      <H4>Importing/exporting dependencies</H4>
242      <P>As well as exporting your main classes and functions (those that are actually
243         documented), Microsoft Visual C++ will warn loudly and often if you try to
244         import/export a class whose dependencies are not also exported. Dependencies
245         include: any base classes, any user defined types used as data members, plus
246         all of the dependencies of your dependencies and so on. This causes particular
247         problems when a dependency is a template class, because although it is
248         technically possible to export these, it is not at all easy, especially if the
249         template itself has dependencies which are implementation-specific details. In
250         most cases it's probably better to simply suppress the warnings using:</P>
251      <PRE>#ifdef BOOST_MSVC
252#  pragma warning(push)
253#  pragma warning(disable : 4251 4231 4660)
254#endif
255
256// code here
257
258#ifdef BOOST_MSVC
259#pragma warning(pop)
260#endif
261</PRE>
262      <p>This is safe provided that there are no dependencies that are (template)
263         classes with non-constant static data members, these really do need exporting,
264         otherwise there will be multiple copies of the static data members in the
265         program, and that's really really bad.
266      </p>
267      <p>Historical note: on 16-bit Windows you really did have to export all
268         dependencies or the code wouldn't work, however since the latest Visual Studio
269         .NET supports the import/export of individual member functions, it's a
270         reasonably safe bet that Windows compilers won't do anything nasty - like
271         changing the class's ABI - when importing/exporting a class.</p>
272      <h4>Rationale:</h4>
273      <p><EM>Why bother - doesn't the import/export mechanism take up more code that the
274            classes themselves?</EM></p>
275      <P>A good point, and probably true, however there are some circumstances where
276         library code must be placed in a shared library - for example when the
277         application consists of multiple dll's as well as the executable, and more than
278         one those dll's link to the same Boost library - in this case if the library
279         isn't dynamically linked and it contains any global data (even if that data is
280         private to the internals of the library) then really bad things can happen -
281         even without global data, we will still get a code bloating effect.
282         Incidentally, for larger applications, splitting the application into multiple
283         dll's can be highly advantageous - by using Microsoft's "delay load" feature
284         the application will load only those parts it really needs at any one time,
285         giving the impression of a much more responsive and faster-loading application.</P>
286      <p><EM>Why static linking by default? </EM>
287      </p>
288      <P>In the worked example above, the code assumes that the library will be
289         statically linked unless the user asks otherwise. Most users seem to prefer
290         this (there are no separate dll's to distribute, and the overall distribution
291         size is often significantly smaller this way as well: i.e. you pay for what you
292         use and no more), but this is a subjective call, and some libraries may even
293         only be available in dynamic versions (Boost.threads for example).</P>
294      <h3><A name="auto-link"></A>Automatic Library Selection and Linking with <a href="../boost/config/auto_link.hpp">
295            auto_link.hpp</a></h3>
296      <p>Many Windows compilers ship with multiple runtime libraries - for example
297         Microsoft Visual Studio .NET comes with 6 versions of the C and C++ runtime. It
298         is essential that the Boost library that the user links to is built against the
299         same C runtime as the program is built against. If that is not the case, then
300         the user will experience linker errors at best, and runtime crashes at worst.
301         The Boost build system manages this by providing different build variants, each
302         of which is build against a different runtime, and gets a slightly different
303         mangled name depending upon which runtime it is built against. For example the
304         regex libraries get named as follows when built with Visual Studio .NET 2003:</p>
305      <pre>boost_regex-vc71-mt-1_31.lib
306boost_regex-vc71-mt-gd-1_31.lib
307libboost_regex-vc71-mt-1_31.lib
308libboost_regex-vc71-mt-gd-1_31.lib
309libboost_regex-vc71-mt-s-1_31.lib
310libboost_regex-vc71-mt-sgd-1_31.lib
311libboost_regex-vc71-s-1_31.lib
312libboost_regex-vc71-sgd-1_31.lib
313</pre>
314      <p>The difficulty now is selecting which of these the user should link his or her
315         code to.</p>
316      <p>In contrast, most Unix compilers typically only have one runtime (or sometimes
317         two if there is a separate thread safe option). For these systems the only
318         choice in selecting the right library variant is whether they want debugging
319         info, and possibly thread safety.
320      </p>
321      <p>Historically Microsoft Windows compilers have managed this issue by providing a
322         #pragma option that allows the header for a library to automatically select the
323         library to link to. This makes everything automatic and extremely easy for the
324         end user: as soon as they include a header file that has separate source code,
325         the name of the right library build variant gets embedded in the object file,
326         and as long as that library is in the linker search path, it will get pulled in
327         by the linker without any user intervention.</p>
328      <p>Automatic library selection and linking can be enabled for a Boost library by
329         including the header &lt;boost/config/auto_link.hpp&gt;, after first defining
330         BOOST_LIB_NAME and, if applicable, BOOST_DYN_LINK.</p>
331      <pre>//
332// Automatically link to the correct build variant where possible.
333//
334#if !defined(BOOST_ALL_NO_LIB) &amp;&amp; !defined(BOOST_WHATEVER_NO_LIB) &amp;&amp; !defined(BOOST_WHATEVER_SOURCE)
335//
336// Set the name of our library, this will get undef'ed by auto_link.hpp
337// once it's done with it:
338//
339#define BOOST_LIB_NAME boost_whatever
340//
341// If we're importing code from a dll, then tell auto_link.hpp about it:
342//
343#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_WHATEVER_DYN_LINK)
344#  define BOOST_DYN_LINK
345#endif
346//
347// And include the header that does the work:
348//
349#include &lt;boost/config/auto_link.hpp&gt;
350#endif  // auto-linking disabled
351</pre>
352      <p>The library's user documentation should note that the feature can be disabled
353         by defining either BOOST_ALL_NO_LIB or BOOST_WHATEVER_NO_LIB:</p>
354      <P>If for any reason you need to debug this feature, the header
355         &lt;boost/config/auto_link.hpp&gt; will output some helpful diagnostic messages
356         if you first define BOOST_LIB_DIAGNOSTIC.</P>
357      <H2><A name="build_changes"></A>Changes Affecting the Build System</H2>
358      <H3><a name="build"></a><A name="jamfile"></A>Creating the library Jamfile</H3>
359      <P>The Jamfile for building library "whatever" typically lives in
360         boost-root/libs/whatever/build, the only extra step required is to add a
361         &lt;define&gt; requirement to the library target so that your code knows
362         whether it's building a dll or static library, a typical Jamfile would like
363         like this:</P>
364      <PRE>
365lib boost_regex : ../src/whatever.cpp :
366  &lt;link&gt;shared:&lt;define&gt;BOOST_WHATEVER_DYN_LINK=1 ;
367 </PRE>
368      <H3><A name="testing"></A>Testing Auto-linking</H3>
369      <P>Testing the auto-link feature&nbsp;is somewhat convoluted, and requires access
370         to a compiler that supports the feature: refer to <A href="../libs/config/test/link/test/Jamfile.v2">
371            libs/config/test/link/test/Jamfile.v2</A> for an example.</P>
372      <HR>
373      <p><A name="copyright"></A>Revised
374         <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
375         26 November, 2003<!--webbot bot="Timestamp" endspan i-checksum="39365" --></p>
376      <p><i>© Copyright John Maddock&nbsp;1998-
377            <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%Y" startspan -->  2003<!--webbot bot="Timestamp" endspan i-checksum="746" --></i></p>
378      <P><I>Distributed under the Boost Software License, Version 1.0. (See accompanying
379            file <a href="../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
380               http://www.boost.org/LICENSE_1_0.txt</a>)</I></P>
381      <P><EM>The use of code snippets from this article does not require the reproduction
382            of this copyright notice and license declaration; if you wish to provide
383            attribution then please provide a link to this article.</EM></P>
384   </body>
385</html>
Note: See TracBrowser for help on using the repository browser.