$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: daniel_james_at_[hidden]
Date: 2007-11-10 10:46:50
Author: danieljames
Date: 2007-11-10 10:46:49 EST (Sat, 10 Nov 2007)
New Revision: 40989
URL: http://svn.boost.org/trac/boost/changeset/40989
Log:
Add the separate compilation page from the old site. Fixes #1370.
Added:
   website/public_html/beta/development/separate_compilation.html   (contents, props changed)
Text files modified: 
   website/public_html/beta/common/menu-development.html |     3 +++                                     
   1 files changed, 3 insertions(+), 0 deletions(-)
Modified: website/public_html/beta/common/menu-development.html
==============================================================================
--- website/public_html/beta/common/menu-development.html	(original)
+++ website/public_html/beta/common/menu-development.html	2007-11-10 10:46:49 EST (Sat, 10 Nov 2007)
@@ -31,6 +31,9 @@
         <li><a href="/development/header.html">Header policy <span class=
         "link">></span></a></li>
 
+        <li><a href="/development/separate_compilation.html">Separate Source
+        <span class="link">></span></a></li>
+
         <li><a href="/development/reuse.html">Library Reuse <span class=
         "link">></span></a></li>
 
Added: website/public_html/beta/development/separate_compilation.html
==============================================================================
--- (empty file)
+++ website/public_html/beta/development/separate_compilation.html	2007-11-10 10:46:49 EST (Sat, 10 Nov 2007)
@@ -0,0 +1,535 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+  <title>Guidelines for Authors of Boost Libraries Containing Separate
+  Source</title>
+  <meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
+  <link rel="icon" href="/favicon.ico" type="image/ico" />
+  <link rel="stylesheet" type="text/css" href=
+  "/style/section-development.css" />
+  <!--[if IE]> <style type="text/css"> body { behavior: url(/style/csshover.htc); } </style> <![endif]-->
+</head>
+
+<body>
+  <div id="heading">
+    <!--#include virtual="/common/heading.html" -->
+  </div>
+
+  <div id="body">
+    <div id="body-inner">
+      <div id="content">
+        <div class="section" id="intro">
+          <div class="section-0">
+            <div class="section-title">
+              <h1>Guidelines for Authors of Boost Libraries Containing
+              Separate Source</h1>
+            </div>
+
+            <div class="section-body">
+              <p>These guidelines are designed for the authors of Boost
+              libraries which have separate source that need compiling in
+              order to use the library. Throughout, this guide refers to a
+              fictitious "whatever" library, so replace all occurrences of
+              "whatever" or "WHATEVER" with your own library's name when
+              copying the examples.</p>
+
+              <h2>Contents</h2>
+
+              <dl class="index">
+                <dt><a href="#source_changes">Changes Affecting Source
+                Code</a></dt>
+
+                <dd>
+                  <dl class="index">
+                    <dt><a href="#abi">Preventing Compiler ABI
+                    Clashes</a></dt>
+
+                    <dt><a href="#static_or_dynamic">Static or Dymanic
+                    Libraries</a></dt>
+
+                    <dt>Supporting Windows Dll's</dt>
+
+                    <dt><a href="#auto-link">Automatic Library Selection and
+                    Linking with auto_link.hpp</a></dt>
+                  </dl>
+                </dd>
+
+                <dt><a href="#build_changes">Changes Affecting the Build
+                System</a></dt>
+
+                <dd>
+                  <dl class="index">
+                    <dt><a href="#jamfile">Creating the Library
+                    Jamfile</a></dt>
+
+                    <dt>Testing Auto-linking</dt>
+                  </dl>
+                </dd>
+
+                <dt>Copyright</dt>
+              </dl>
+
+              <h2><a name="source_changes" id="source_changes"></a>Changes
+              Affecting Source Code</h2>
+
+              <h3><a name="abi" id="abi"></a>Preventing Compiler ABI
+              Clashes</h3>
+
+              <p>There are some compilers (mostly Microsoft Windows compilers
+              again!), which feature a range of compiler switches that alter
+              the ABI of C++ classes and functions. By way of example,
+              consider Borland's compiler which has the following
+              options:</p>
+              <pre>
+-b    (on or off - effects enum sizes).
+-Vx   (on or off - empty members).
+-Ve   (on or off - empty base classes).
+-aX   (alignment - 5 options).
+-pX   (Calling convention - 4 options).
+-VmX  (member pointer size and layout - 5 options).
+-VC   (on or off, changes name mangling).
+-Vl   (on or off, changes struct layout). 
+</pre>
+
+              <p>These options are provided in addition to those affecting
+              which runtime library is used (more on which later); the total
+              number of combinations of options can be obtained by
+              multiplying together the individual options above, so that
+              gives 2*2*2*5*4*5*2*2 = 3200 combinations!</p>
+
+              <p>The problem is that users often expect to be able to build
+              the Boost libraries and then just link to them and have
+              everything just plain work, no matter what their project
+              settings are. Irrespective of whether this is a reasonable
+              expectation or not, without some means of managing this issue,
+              the user may well find that their program will experience
+              strange and hard to track down crashes at runtime unless the
+              library they link to was built with the same options as their
+              project (changes to the default alignment setting are a prime
+              culprit). One way to manage this is with "prefix and suffix"
+              headers: these headers invoke compiler specific #pragma
+              directives to instruct the compiler that whatever code follows
+              was built (or is to be built) with a specific set of compiler
+              ABI settings.</p>
+
+              <p>Boost.config provides the macro BOOST_HAS_ABI_HEADERS which
+              is set whenever there are prefix and suffix headers available
+              for the compiler in use, typical usage in a header like
+              this:</p>
+              <pre>
+#ifndef BOOST_WHATEVER_HPP
+#define BOOST_WHATEVER_HPP
+
+#include <boost/config.hpp>
+
+// this must occur after all of the includes and before any code appears:
+#ifdef BOOST_HAS_ABI_HEADERS
+#  include BOOST_ABI_PREFIX
+#endif
+//
+// this header declares one class, and one function by way of examples:
+//
+class whatever
+{
+   // details.
+};
+
+whatever get_whatever();
+
+// the suffix header occurs after all of our code:
+#ifdef BOOST_HAS_ABI_HEADERS
+#  include BOOST_ABI_SUFFIX
+#endif
+
+#endif
+</pre>
+
+              <p>You can include this code in your library source files as
+              well if you want, although you probably shouldn't need to:</p>
+
+              <ul>
+                <li>If you <em>don't</em> use these in the library source
+                files (but do in your library's headers) and the user
+                attempts to compile the library source with a non-default ABI
+                setting, then they will get compiler errors if there are any
+                conflicts.</li>
+
+                <li>If you <em>do</em> include them in both the library's
+                headers and the library source files, then the code should
+                always compile no matter what the compiler settings used,
+                although the result might not match what the user was
+                expecting: since we've forced the ABI back into default
+                mode.</li>
+              </ul>
+
+              <h4>Rationale:</h4>
+
+              <p>Without some means of managing this issue, users often
+              report bugs along the line of "Your silly library always
+              crashes when I try and call it" and so on. These issues can be
+              extremely difficult and time consuming to track down, only to
+              discover in the end that it's a compiler setting that's changed
+              the ABI of the class and/or function types of the program
+              compared to those in the pre-compiled library. The use of
+              prefix/suffix headers can minimize this problem, although
+              probably not remove it completely.</p>
+
+              <h5>Counter Argument #1:</h5>
+
+              <p>Trust the user, if they want 13-byte alignment (!) let them
+              have it.</p>
+
+              <h5>Counter Argument #2:</h5>
+
+              <p>Prefix/suffix headers have a tendency to "spread" to other
+              boost libraries - for example if boost::shared_ptr<>
+              forms part of your class's ABI, then including prefix/suffix
+              headers in your code will be of no use unless shared_ptr.hpp
+              also uses them. Authors of header-only boost libraries may not
+              be so keen on this solution - with some justification - since
+              they don't face the same problem.</p>
+
+              <h3><a name="static_or_dynamic" id=
+              "static_or_dynamic"></a>Static or Dynamic Libraries</h3>
+
+              <p>When the users runtime is dynamically linked the Boost
+              libraries can be built either as dynamic libraries (.so's on
+              Unix platforms, .dll's on Windows) or as static libraries (.a's
+              on Unix, .lib's on Windows). So we have a choice as to which is
+              supported by default:</p>
+
+              <ul>
+                <li>On Unix platforms it typically makes no difference to the
+                code: the user just selects in their makesfile which library
+                they prefer to link to.</li>
+
+                <li>On Windows platforms, the code has to be specially
+                annotated to support DLL's, so we need to pick one option as
+                the default and one as an alternative.</li>
+
+                <li>On Windows platforms, we can inject special code to
+                automatically select which library variant to link against:
+                so again we need to decide which is to be the default (see
+                the section on auto-linking below).</li>
+              </ul>
+
+              <p>The recomendation is to pick static linking by default.</p>
+
+              <h4>Rationale:</h4>
+
+              <p>There is no one policy that fits all here.</p>
+
+              <p>The rationale for the current behaviour was inherited from
+              Boost.Regex (and it's ancestor regex++): this library
+              originally used dynamic linking by default whenever the runtime
+              was dynamic. It's actually safer that way should you be using
+              regex from a dll for example. However, this behavior brought a
+              persistent stream of user complaints: mainly about deployment,
+              all asking if static linking could be the default. After regex
+              changed behavior the complaints stopped, and the author hasn't
+              had one complaint about static linking by default being the
+              wrong choice.</p>
+
+              <p>Note that other libraries might need to make other choices:
+              for example libraries that are intended to be used to implement
+              dll pluggin's would like need to use dynamic linking in almost
+              all cases.</p>
+
+              <h3>Supporting Windows Dll's</h3>
+
+              <p>On most Unix-like platforms no special annotations of source
+              code are required in order for that source to be compiled as a
+              shared library because all external symbols are exposed.
+              However the majority of Windows compilers require that symbols
+              that are to be imported or exported from a dll, be prefixed
+              with __declspec(dllimport) or __declspec(dllexport). Without
+              this mangling of source code, it is not possible to correctly
+              build shared libraries on Windows (historical note - originally
+              these declaration modifiers were required on 16-bit Windows
+              where the memory layout for exported classes was different from
+              that of "local" classes - although this is no longer an issue,
+              there is still no way to instruct the linker to "export
+              everything", it also remains to be seen whether 64-bit Windows
+              will resurrect the segmented architecture that led to this
+              problem in the first place. Note also that the mangled names of
+              exported symbols are different from non-exported ones, so
+              __declspec(dllimport) is required in order to link to code
+              within a dll).</p>
+
+              <p>In order to support the building of shared libraries on MS
+              Windows your code will have to prefix all the symbols that your
+              library exports with a macro (lets call it BOOST_WHATEVER_DECL)
+              that your library will define to expand to either
+              __declspec(dllexport) or __declspec(dllimport) or nothing,
+              depending upon how your library is being built or used. Typical
+              usage would look like this:</p>
+              <pre>
+#ifndef BOOST_WHATEVER_HPP
+#define BOOST_WHATEVER_HPP
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_HAS_DECLSPEC // defined in config system
+// we need to import/export our code only if the user has specifically
+// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
+// libraries to be dynamically linked, or BOOST_WHATEVER_DYN_LINK
+// if they want just this one to be dynamically liked:
+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_WHATEVER_DYN_LINK)
+// export if this is our own source, otherwise import:
+#ifdef BOOST_WHATEVER_SOURCE
+# define BOOST_WHATEVER_DECL __declspec(dllexport)
+#else
+# define BOOST_WHATEVER_DECL __declspec(dllimport)
+#endif  // BOOST_WHATEVER_SOURCE
+#endif  // DYN_LINK
+#endif  // BOOST_HAS_DECLSPEC
+//
+// if BOOST_WHATEVER_DECL isn't defined yet define it now:
+#ifndef BOOST_WHATEVER_DECL
+#define BOOST_WHATEVER_DECL
+#endif
+
+//
+// this header declares one class, and one function by way of examples:
+//
+class BOOST_WHATEVER_DECL whatever
+{
+   // details.
+};
+
+BOOST_WHATEVER_DECL whatever get_whatever();
+
+#endif
+</pre>And then in the source code for this library one would use:
+              <pre>
+ 
+// 
+// define BOOST_WHATEVER SOURCE so that our library's 
+// setup code knows that we are building the library (possibly exporting code), 
+// rather than using it (possibly importing code): 
+// 
+#define BOOST_WHATEVER_SOURCE 
+#include <boost/whatever.hpp> 
+
+// class members don't need any further annotation: 
+whatever::whatever() { } 
+// but functions do: 
+BOOST_WHATEVER_DECL whatever get_whatever() 
+{
+   return whatever();
+}
+</pre>
+
+              <h4>Importing/exporting dependencies</h4>
+
+              <p>As well as exporting your main classes and functions (those
+              that are actually documented), Microsoft Visual C++ will warn
+              loudly and often if you try to import/export a class whose
+              dependencies are not also exported. Dependencies include: any
+              base classes, any user defined types used as data members, plus
+              all of the dependencies of your dependencies and so on. This
+              causes particular problems when a dependency is a template
+              class, because although it is technically possible to export
+              these, it is not at all easy, especially if the template itself
+              has dependencies which are implementation-specific details. In
+              most cases it's probably better to simply suppress the warnings
+              using:</p>
+              <pre>
+#ifdef BOOST_MSVC
+#  pragma warning(push)
+#  pragma warning(disable : 4251 4231 4660)
+#endif
+
+// code here
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+</pre>
+
+              <p>This is safe provided that there are no dependencies that
+              are (template) classes with non-constant static data members,
+              these really do need exporting, otherwise there will be
+              multiple copies of the static data members in the program, and
+              that's really really bad.</p>
+
+              <p>Historical note: on 16-bit Windows you really did have to
+              export all dependencies or the code wouldn't work, however
+              since the latest Visual Studio .NET supports the import/export
+              of individual member functions, it's a reasonably safe bet that
+              Windows compilers won't do anything nasty - like changing the
+              class's ABI - when importing/exporting a class.</p>
+
+              <h4>Rationale:</h4>
+
+              <p><em>Why bother - doesn't the import/export mechanism take up
+              more code that the classes themselves?</em></p>
+
+              <p>A good point, and probably true, however there are some
+              circumstances where library code must be placed in a shared
+              library - for example when the application consists of multiple
+              dll's as well as the executable, and more than one those dll's
+              link to the same Boost library - in this case if the library
+              isn't dynamically linked and it contains any global data (even
+              if that data is private to the internals of the library) then
+              really bad things can happen - even without global data, we
+              will still get a code bloating effect. Incidentally, for larger
+              applications, splitting the application into multiple dll's can
+              be highly advantageous - by using Microsoft's "delay load"
+              feature the application will load only those parts it really
+              needs at any one time, giving the impression of a much more
+              responsive and faster-loading application.</p>
+
+              <p><em>Why static linking by default?</em></p>
+
+              <p>In the worked example above, the code assumes that the
+              library will be statically linked unless the user asks
+              otherwise. Most users seem to prefer this (there are no
+              separate dll's to distribute, and the overall distribution size
+              is often significantly smaller this way as well: i.e. you pay
+              for what you use and no more), but this is a subjective call,
+              and some libraries may even only be available in dynamic
+              versions (Boost.threads for example).</p>
+
+              <h3><a name="auto-link" id="auto-link"></a>Automatic Library
+              Selection and Linking with <a href=
+              "../boost/config/auto_link.hpp">auto_link.hpp</a></h3>
+
+              <p>Many Windows compilers ship with multiple runtime libraries
+              - for example Microsoft Visual Studio .NET comes with 6
+              versions of the C and C++ runtime. It is essential that the
+              Boost library that the user links to is built against the same
+              C runtime as the program is built against. If that is not the
+              case, then the user will experience linker errors at best, and
+              runtime crashes at worst. The Boost build system manages this
+              by providing different build variants, each of which is build
+              against a different runtime, and gets a slightly different
+              mangled name depending upon which runtime it is built against.
+              For example the regex libraries get named as follows when built
+              with Visual Studio .NET 2003:</p>
+              <pre>
+boost_regex-vc71-mt-1_31.lib
+boost_regex-vc71-mt-gd-1_31.lib
+libboost_regex-vc71-mt-1_31.lib
+libboost_regex-vc71-mt-gd-1_31.lib
+libboost_regex-vc71-mt-s-1_31.lib
+libboost_regex-vc71-mt-sgd-1_31.lib
+libboost_regex-vc71-s-1_31.lib
+libboost_regex-vc71-sgd-1_31.lib
+</pre>
+
+              <p>The difficulty now is selecting which of these the user
+              should link his or her code to.</p>
+
+              <p>In contrast, most Unix compilers typically only have one
+              runtime (or sometimes two if there is a separate thread safe
+              option). For these systems the only choice in selecting the
+              right library variant is whether they want debugging info, and
+              possibly thread safety.</p>
+
+              <p>Historically Microsoft Windows compilers have managed this
+              issue by providing a #pragma option that allows the header for
+              a library to automatically select the library to link to. This
+              makes everything automatic and extremely easy for the end user:
+              as soon as they include a header file that has separate source
+              code, the name of the right library build variant gets embedded
+              in the object file, and as long as that library is in the
+              linker search path, it will get pulled in by the linker without
+              any user intervention.</p>
+
+              <p>Automatic library selection and linking can be enabled for a
+              Boost library by including the header
+              <boost/config/auto_link.hpp>, after first defining
+              BOOST_LIB_NAME and, if applicable, BOOST_DYN_LINK.</p>
+              <pre>
+//
+// Automatically link to the correct build variant where possible. 
+// 
+#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_WHATEVER_NO_LIB) && !defined(BOOST_WHATEVER_SOURCE)
+//
+// Set the name of our library, this will get undef'ed by auto_link.hpp
+// once it's done with it:
+//
+#define BOOST_LIB_NAME boost_whatever
+//
+// If we're importing code from a dll, then tell auto_link.hpp about it:
+//
+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_WHATEVER_DYN_LINK)
+#  define BOOST_DYN_LINK
+#endif
+//
+// And include the header that does the work:
+//
+#include <boost/config/auto_link.hpp>
+#endif  // auto-linking disabled
+</pre>
+
+              <p>The library's user documentation should note that the
+              feature can be disabled by defining either BOOST_ALL_NO_LIB or
+              BOOST_WHATEVER_NO_LIB:</p>
+
+              <p>If for any reason you need to debug this feature, the header
+              <boost/config/auto_link.hpp> will output some helpful
+              diagnostic messages if you first define
+              BOOST_LIB_DIAGNOSTIC.</p>
+
+              <h2><a name="build_changes" id="build_changes"></a>Changes
+              Affecting the Build System</h2>
+
+              <h3><a name="build" id="build"></a><a name="jamfile" id=
+              "jamfile"></a>Creating the library Jamfile</h3>
+
+              <p>The Jamfile for building library "whatever" typically lives
+              in boost-root/libs/whatever/build, the only extra step required
+              is to add a <define> requirement to the library target so
+              that your code knows whether it's building a dll or static
+              library, a typical Jamfile would like like this:</p>
+              <pre>
+lib boost_regex : ../src/whatever.cpp : 
+  <link>shared:<define>BOOST_WHATEVER_DYN_LINK=1 ;
+ 
+</pre>
+
+              <h3><a name="testing" id="testing"></a>Testing
+              Auto-linking</h3>
+
+              <p>Testing the auto-link feature is somewhat convoluted, and
+              requires access to a compiler that supports the feature: refer
+              to <a href=
+              "../libs/config/test/link/test/Jamfile.v2">libs/config/test/link/test/Jamfile.v2</a>
+              for an example.</p>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div id="sidebar">
+        <!--#include virtual="/common/sidebar-common.html" -->
+        <!--#include virtual="/common/sidebar-development.html" -->
+      </div>
+
+      <div class="clear"></div>
+    </div>
+  </div>
+
+  <div id="footer">
+    <div id="footer-left">
+      <div id="revised">
+        <p>Revised $Date: 2007-10-22 22:55:52 +0100 (Mon, 22 Oct 2007) $</p>
+      </div>
+
+      <div id="copyright">
+        <p>Copyright John Maddock 1998.</p>
+      </div><!--#include virtual="/common/footer-license.html" -->
+    </div>
+
+    <div id="footer-right">
+      <!--#include virtual="/common/footer-banners.html" -->
+    </div>
+
+    <div class="clear"></div>
+  </div>
+</body>
+</html>