Boost logo

Boost :

From: Steven Dodd (sdodd_at_[hidden])
Date: 2008-05-12 11:31:03


I think it would be worthwhile to extend Boost to support GCC's (relatively) new visibility features.

For those unfamiliar with GCC's visibility features, please read the following articles for background:

    http://gcc.gnu.org/wiki/Visibility
    http://developer.apple.com/technotes/tn2007/tn2185.html

Please forgive any ignorance displayed in the following proposal - I'm new to Boost, and only more-so to Boost library development! I've reviewed all of the messages I could find on the mailing list related to this subject, but didn't see one that provided a comprehensive proposal for adding full visibility support. So here goes:

There are essentially two use-cases which need to be addressed:

( 1 ) Compiling Boost with restricted visibility

In this case, the user wants to gain the full benefits of restricted symbol visibility, and so they want to compile both their own code and Boost with restricted symbol visibility. That is, they want to build Boost with some combination of the GCC flags: -fvisibility=hidden, -fvisibility-inlines-hidden, and -fvisibility-ms-compat (OS X specific).

In order to build Boost properly with restricted symbol visibility, Boost needs to be configured to mark all public symbols as such.

On Windows, Boost already does this by (A) defining BOOST_HAS_DECLSPEC in <config/platform/win32.hpp>, and (B) defining and using library-specific _DECL macros (e.g. BOOST_FILESYSTEM_DECL = __declspec(dllexport) or __declspec(dllimport) depending on whether the library is being built, or used).

What needs to be done to support GCC's symbol visibility restriction is to generalize the support already in place for Windows, along the following lines:

- Rename BOOST_HAS_DECLSPEC to BOOST_HAS_SYM_CONTROL, and define this symbol in appropriate config headers. For GCC, this should be an optional feature, and I'm not sure of how to best allow users to enable/disable it (e.g. how to integrate it as a Boost.Build option). Change all locations to use the new name.
- Introduce macro, BOOST_SYM_EXPORT, and define as __declspec(dllexport) on Windows, and as __attribute__((visibility("default"))) for GCC. Change all locations currently hard-coding __declspec( dllexport ) to use BOOST_SYM_EXPORT instead.
- Introduce macro, BOOST_SYM_IMPORT, and define as __declspec(dllimport) on Windows, and as __attribute__((visibility("default"))) for GCC. Change all locations currently hard-coding __declspec( dllimport ) to use BOOST_SYM_IMPORT instead.

This approach should work "out-of-the-box" when using GCC's -fvisibility-ms-compat mode (MSVC++ compatibility mode), since it already works on Windows.

However, this approach will likely be incomplete when using GCC's -fvisibility=hidden mode. Reason being, unlike the visibility-ms-compat mode, this mode does not automatically mark types with "vague linkage" as visible (e.g. type_info). As a result, exceptions thrown in one DSO will not be caught in other DSOs. It is beyond my understanding of Boost to propose a comprehensive set of changes required to address the problem.

( 2 ) Compiling Boost with normal visibility, but enabling linkage into user-code compiled with restricted visibility

In this case, the user wants to build their own code with restricted symbol visibility, but wants to link against a copy of Boost compiled with default visibility (e.g. most likely, a pre-built Boost binary). Presently, upon doing so, the user will find themselves faced with a slew of linker warnings regarding the mismatch in visibility levels between Boost symbols compiled into user-code vs. in the Boost libraries.

In order to resolve this issue properly (e.g. not just silence the linker), Boost needs to be modified to wrap all Boost types in "default" visibility instructions, like so:

#pragma GCC visibility push(default)

... boost types ...

#pragma GCC visibility pop

Boost's existing ABI facility is sufficient for this task, were it employed consistently by all Boost libraries (unfortunately, as far as I can tell, it is not):

- Create file <boost/config/abi/gcc_default_visibility_prefix.hpp> with the following contents:

#pragma GCC visibility push(default)

- Create file <boost/config/abi/gcc_default_visibility_suffix.hpp> with the following contents:

#pragma GCC visibility pop

- In the appropriate config header, define BOOST_ABI_PREFIX as "boost/config/abi/gcc_default_visibility_prefix.hpp", define BOOST_ABI_SUFFIX as "boost/config/abi/gcc_default_visibility_suffix.hpp", and define BOOST_HAS_ABI_HEADERS. Note: this should be the default for GCC, however, if the user has requested restricted symbol visibility, as in use-case (1), then these BOOST*ABI macros must not be defined, or the prefix/suffix headers at least need to conditionally define the visibility based on some other macro definition...

I look forward to comments!

Cheers,

Steven Dodd
sdodd<at>view22<dot>com


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk