Subject: Re: [boost] support for gcc hidden visibility in shared libraries
From: Alexander Arhipenko (arhipjan_at_[hidden])
Date: 2008-12-11 08:54:25


Guys, while reading through your fruitful comments, I've became to the
following conclusions:

1. We should preserve default behavior of each toolset when building boost,
    e.g., for gcc compilation should be performed with visibility=default
2. We should give the ability to users:
    a) simplify build of custom libraries by providing macros such as
BOOST_SYMBOL_EXPORT etc
    b) build needed boost library with custom visibility (hidden,
ms-compat etc).

All this ideas are implemented in attached patches.

The first patch is for boost-build.
It provides new composite feature 'hide-symbols' with available options:
on, off, ms-compat, inlines-hidden.
So, if I would like to build filesystem with hidden visibility, I can
do the followings:
* In boost root directory type "bjam /boost/filesystem hide-symbols=on"
* In my library's Jamfile:
    alias filesystem : /boost/filesystem : <hide-symbols>on ;

'hide-symbols' feature should work only for gcc and darwin toolsets.
For the others it does nothing.
Unfortunately I had no ability to test darwin.

It worth mentioning that I'm not a boost.build expert, so this patch
supposed to be
rather *ugly* and should be carefully reviewed by some boost.build guy.

The second patch affects all the boost configuration files with
BOOST_XXX_DECL macroses:
__declspec(dllexport)/(dllimort) are simply replaced with macroses
BOOST_SYBMOL_EXPORT/IMPORT.

As you may see, attached patches preserve default behavior of boost
build procedure.

Unit tests.
I've performed unit testing for affected libraries (with gcc (GCC)
4.1.2 20071124 (Red Hat 4.1.2-42) ).
All of them (except serialization) was built with hidden visibility.
It was 2 failures in program_options (as Andrey predicted ;) ) in
BOOST_CHECK_THROW:
exception wasn't caught (variable_map_test_dll, unicode_test_dll).
All the others run smoothly (unless I missed something).

Exceptions.
This worries me a lot, since all the exceptions that wasn't *properly
exported* will never be caught.
Saying *properly exported* I mean:
  they always have default visibility
   or
  have been exported from shared library and have at least one key function,
  i.e. "non-pure virtual function that is not inline at the point of
class definition"

To reproduce this issue, you can try to build attached sample project
and run ./install/fee_client /some/invalid/path:
boost::filesystem_error and boost::system_error won't be caught.
(Note, dependent boost libraries should be build with default visibility).

Regards

P.S. Again, comments and questions will be really apreciated