diff --git a/doc/macro_reference.qbk b/doc/macro_reference.qbk index 0843da53..94dd204f 100644 --- a/doc/macro_reference.qbk +++ b/doc/macro_reference.qbk @@ -317,6 +317,7 @@ void g() { return f(); } [#config_features] + [section Macros that describe optional features] The following macros describe features that are not required by the C++ @@ -332,10 +333,6 @@ The platform supports BeOS style threads. [[`BOOST_HAS_CLOCK_GETTIME`][Platform][ The platform has the POSIX API `clock_gettime`. ]] -[[`BOOST_HAS_DECLSPEC`][Compiler][ -The compiler uses `__declspec(dllexport)` and `__declspec(dllimport)` to -export/import symbols from dll's. -]] [[`BOOST_HAS_DIRENT_H`][Platform][ The platform has the POSIX header ``. ]] @@ -868,9 +865,98 @@ the configuration. [section Macros for libraries with separate source code] The following macros and helper headers are of use to authors whose libraries -include separate source code, and are intended to address two issues: fixing -the ABI of the compiled library, and selecting which compiled library to link -against based upon the compilers settings. +include separate source code, and are intended to address several issues: + +* Controlling shared library symbol visibility +* Fixing the ABI of the compiled library +* Selecting which compiled library to link against based upon the compilers settings + +See [@http://svn.boost.org/trac/boost/wiki/Guidelines/Separate Guidelines for Authors of Boost Libraries Containing Separate Source] + +[section Macros controlling shared library symbol visibility] + +Some compilers support C++ extensions that control which symbols +will be exported from shared libraries such as dynamic shared objects (DSO's) on Unix-like +systems or dynamic-link libraries (DLL's) on Windows. + +The Microsoft VC++ compiler has long supplied +`__declspec(dllexport)` and `__declspec(dllimport)` extensions for this purpose, +as do virtually all other compilers targeting the Windows platform. + +Modern versions of the GNU GCC compiler provide the `__attribute__((visibility("default")))` +extension to indicate that a symbol should be exported. All other symbols may be hidden by using the +`-fvisibility-hidden` or `-fvisibility-ms-compat` compiler switches. + +Boost supplies several macros to make it easier to manage symbol visibility in a way that +is portable between compilers and operating systems. + +[table +[[Macro ][Description ]] +[[`BOOST_SYMBOL_EXPORT`][ +Defines the syntax of a C++ language extension that indicates a symbol is to be exported from a shared library. +If the compiler has no such extension, the macro is defined with no replacement text. +]] +[[`BOOST_SYMBOL_IMPORT`][ +Defines the syntax of a C++ language extension that indicates a symbol is to be imported from a shared library. +If the compiler has no such extension, the macro is defined with no replacement text. +]] +[[`BOOST_SYMBOL_VISIBLE`][ +Defines the syntax of a C++ language extension that indicates a symbol is to be globally visible. +If the compiler has no such extension, the macro is defined with no replacement text. +Needed for classes that are not otherwise exported, but are used by RTTI. Examples include +class for objects that will be thrown as exceptions or used in dynamic_casts, +across shared library boundaries. For example, a header-only exception class might look like this: +`` + class BOOST_SYMBOL_VISIBLE my_exception : public std::runtime_error { ... }; +`` +Without BOOST_SYMBOL_VISIBLE, it would be impossible to catch my_exception thrown from a shared library +compiled by GCC with the -fvisibility=hidden option. +]] +[[`BOOST_HAS_DECLSPEC`][ +The compiler has C++ extensions `__declspec(dllexport)` and `__declspec(dllimport)` to control +export/import of symbols from shared libraries. +['Deprecated. This macro is no longer necessary since BOOST_SYMBOL_EXPORT and BOOST_SYMBOL_IMPORT +are now supplied. It is provided to support legacy code.] +]] +] + +Typical usage: + +[*boost/foo/config.hpp] + + ... + #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FOO_DYN_LINK) + # if defined(BOOST_FOO_SOURCE) + # define BOOST_FOO_DECL BOOST_SYMBOL_EXPORT + # else + # define BOOST_FOO_DECL BOOST_SYMBOL_IMPORT + # endif + #else + # define BOOST_FOO_DECL + #endif + ... + +[*boost/foo/foo.hpp] + + #include + ... + class BOOST_FOO_DECL bar { ... }; + ... + void BOOST_FOO_DECL f(); + ... + +[*boost/libs/foo/src/foo.cpp] + + #define BOOST_FOO_SOURCE + #include + ... + void BOOST_FOO_DECL f() + { + ... + } + ... + +[endsect] [section ABI Fixing] diff --git a/include/boost/config/compiler/borland.hpp b/include/boost/config/compiler/borland.hpp index fecc29aa..bd3a8c3f 100644 --- a/include/boost/config/compiler/borland.hpp +++ b/include/boost/config/compiler/borland.hpp @@ -230,8 +230,9 @@ // // all versions support __declspec: // -#ifndef __STRICT_ANSI__ -# define BOOST_HAS_DECLSPEC +#if defined(__STRICT_ANSI__) +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT #endif // // ABI fixing headers: diff --git a/include/boost/config/compiler/clang.hpp b/include/boost/config/compiler/clang.hpp index e5a682b2..7aac8c35 100644 --- a/include/boost/config/compiler/clang.hpp +++ b/include/boost/config/compiler/clang.hpp @@ -18,12 +18,6 @@ # define BOOST_NO_RTTI #endif -#if defined(__int32) -// HACK: Clang only defines the type __int32 in Microsoft-compatibility mode, -// which means that declspecs are also available -# define BOOST_HAS_DECLSPEC -#endif - #if defined(__int64) # define BOOST_HAS_MS_INT64 #endif diff --git a/include/boost/config/compiler/codegear.hpp b/include/boost/config/compiler/codegear.hpp index 9cb061ff..f6dc4c02 100644 --- a/include/boost/config/compiler/codegear.hpp +++ b/include/boost/config/compiler/codegear.hpp @@ -147,8 +147,9 @@ // // all versions support __declspec: // -#if !defined(__STRICT_ANSI__) -# define BOOST_HAS_DECLSPEC +#if defined(__STRICT_ANSI__) +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT #endif // // ABI fixing headers: diff --git a/include/boost/config/compiler/gcc.hpp b/include/boost/config/compiler/gcc.hpp index b9b42bdb..3ba45ddd 100644 --- a/include/boost/config/compiler/gcc.hpp +++ b/include/boost/config/compiler/gcc.hpp @@ -108,6 +108,28 @@ #if __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 1 ) #define BOOST_HAS_NRVO #endif + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if __GNUC__ >= 4 +# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + // All Win32 development environments, including 64-bit Windows and MinGW, define + // _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment, + // so does not define _WIN32 or its variants. +# define BOOST_HAS_DECLSPEC +# define BOOST_SYMBOL_EXPORT __attribute__((dllexport)) +# define BOOST_SYMBOL_IMPORT __attribute__((dllimport)) +# else +# define BOOST_SYMBOL_EXPORT __attribute__((visibility("default"))) +# define BOOST_SYMBOL_IMPORT +# endif +# define BOOST_SYMBOL_VISIBLE __attribute__((visibility("default"))) +#else +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT +#endif + // // RTTI and typeinfo detection is possible post gcc-4.3: // diff --git a/include/boost/config/compiler/visualc.hpp b/include/boost/config/compiler/visualc.hpp index e52ddcec..2f89519e 100644 --- a/include/boost/config/compiler/visualc.hpp +++ b/include/boost/config/compiler/visualc.hpp @@ -163,11 +163,6 @@ # define BOOST_NO_RTTI #endif -// -// all versions support __declspec: -// -#define BOOST_HAS_DECLSPEC - // // C++0x features // diff --git a/include/boost/config/platform/win32.hpp b/include/boost/config/platform/win32.hpp index 9344818f..f59c4ea7 100644 --- a/include/boost/config/platform/win32.hpp +++ b/include/boost/config/platform/win32.hpp @@ -21,10 +21,17 @@ # define BOOST_NO_SWPRINTF #endif -#if !defined(__GNUC__) && !defined(BOOST_HAS_DECLSPEC) +// Default defines for BOOST_SYMBOL_EXPORT and BOOST_SYMBOL_IMPORT +// If a compiler doesn't support __declspec(dllexport)/__declspec(dllimport), +// its boost/config/compiler/ file must define BOOST_SYMBOL_EXPORT and +// BOOST_SYMBOL_IMPORT +#ifndef BOOST_SYMBOL_EXPORT # define BOOST_HAS_DECLSPEC +# define BOOST_SYMBOL_EXPORT __declspec(dllexport) +# define BOOST_SYMBOL_IMPORT __declspec(dllimport) #endif + #if defined(__MINGW32__) && ((__MINGW32_MAJOR_VERSION > 2) || ((__MINGW32_MAJOR_VERSION == 2) && (__MINGW32_MINOR_VERSION >= 0))) # define BOOST_HAS_STDINT_H # define __STDC_LIMIT_MACROS diff --git a/include/boost/config/suffix.hpp b/include/boost/config/suffix.hpp index 019c9ea0..3408d225 100644 --- a/include/boost/config/suffix.hpp +++ b/include/boost/config/suffix.hpp @@ -25,6 +25,19 @@ #ifndef BOOST_CONFIG_SUFFIX_HPP #define BOOST_CONFIG_SUFFIX_HPP +// +// ensure that visibility macros are always defined, thus symplifying use +// +#ifndef BOOST_SYMBOL_EXPORT +# define BOOST_SYMBOL_EXPORT +#endif +#ifndef BOOST_SYMBOL_IMPORT +# define BOOST_SYMBOL_IMPORT +#endif +#ifndef BOOST_SYMBOL_VISIBLE +# define BOOST_SYMBOL_VISIBLE +#endif + // // look for long long by looking for the appropriate macros in . // Note that we use limits.h rather than climits for maximal portability,