Boost logo

Boost :

Subject: Re: [boost] [config] Request for BOOST_SYMBOL_IMPORT_VISIBLE ?
From: Alexander Arhipenko (arhipjan_at_[hidden])
Date: 2011-02-12 05:53:41


On Tue, Feb 8, 2011 at 3:15 PM, John Maddock <boost.regex_at_[hidden]> wrote:
>> One question:
>> what is wrong with having BOOST_SYMBOL_IMPORT defined as it is?
>> The only issues we can have is the "malfunctioning exceptions" and
>> "mulfunctioning dynamic_cast" operator. To overcome these, symbols
>> should be re-exported.
>> Could you please provide some motivation to changing BOOST_SYMBOL_IMPORT?
>
> It's to fix those two issue.
>
> Note that as library authors *we have no way of knowing when re-export is
> required*, but re-export requires a change to *our headers*.
>
> That's the fundamental issue we're trying to solve.
>

I agree with you that re-export requires a change to headers.
I can't fully agree on *we have no way of knowing when re-export is required*.
If you export concrete class it's for sure does not require re-export.
If the library has an exception class that could leave library's boundary -
it should be re-exported.

> [snip]
>
> Sure, the question I'm still looking for someone to answer, is "what does
> re-exporting actually do to increase startup bloat"?  Remember the .so
> that's doing the re-exporting doesn't have access to the definitions of
> re-exported classes, only the declaration.  So presumably (based on no
> evidence at all!) only RTTI info for polymorphic classes will be
> re-exported, which is pretty much what we want to have happen anyway?
>
> OK, I see these options:
>
> 1) Do nothing, have the user set whatever macro is used to control
> *exporting* symbols from a Boost .so when they want to re-export that lib.
> 2) Do almost nothing, but have a Boost-wide macro that changes dll-import to
> default visibility, and re-export all Boost symbols.
> 3) Re-export all imported symbols by default, but have a way to turn that
> off.
>
> What I'm trying to avoid is:
>
> 4) Fine grained macros that give different visibility to different symbols -
> we have enough trouble keeping this all working as it is!
>
> Thoughts?
>
> John.
>

I aggree on the bullets above but have some comments.

As you mentioned, boost should provide the most simplest solution.
But it should also leave an option to boost user's and boost libraries
maintainers
on how to export/import/re-export symbols from dso.
The ideal solution for me would be to have following default behavior:

1) regular symbols are exported as they are now (without re-export)
2) public exceptions are re-exported

For this, boost.config should have additional macro:
BOOST_SYMBOL_IMPORT_REEXPORT.
It unrolls to BOOST_SYMBOL_IMPORT on platforms
that provide "declspec" macros set.
It unrolls to following on platforms that have "visibility" stuff:
#define BOOST_SYMBOL_IMPORT_REEXPORT \
 __attribute__((visibility("default"))

It will be up to library's maintener to decide what symbols to export,
reexport, what hide. Having current set of BOOST_SYMBOL_* macros
+ BOOST_SYMBOL_IMPORT_REEXPORT it's possible to implement
default functionality (mentioned above) and also
some more sophisticated stuff.

Consider example below on how "default" export/import could be implemented.
(Assume library name is A).

#if defined BOOST_A_BUILD_SHLIB
# define BOOST_A_DECL BOOST_SYMBOL_EXPORT
# define BOOST_A_DECL_VISIBLE BOOST_A_DECL
#elif defined BOOST_A_USE_SHLIB
# define BOOST_A_DECL BOOST_SYMBOL_IMPORT
# define BOOST_A_DECL_VISIBLE BOOST_SYMBOL_IMPORT_REEXPORT
#endif

namespace boost { namespace alib {

   class BOOST_A_DECL myclass {/*...*/};
   class BOOST_A_DECL_VISIBLE myerror {/*...*/};

}}

Consider more sophisticated example.
A's library author could give an option to the users
not to re-export any classes.
If someone builds library B and links library A and
defines BOOST_A_IMPORT_PRIVATE macro,
no symbols will be re-exported from A library.

#if defined BOOST_A_IMPORT_PRIVATE
# define BOOST_A_IMPORT BOOST_SYMBOL_IMPORT
#else
# define BOOST_A_IMPORT BOOST_SYMBOL_IMPORT_REEXPORT
#endif

#if defined BOOST_A_BUILD_SHLIB
# define BOOST_A_DECL BOOST_SYMBOL_EXPORT
# define BOOST_A_DECL_VISIBLE BOOST_A_DECL
#elif defined BOOST_A_USE_SHLIB
# define BOOST_A_DECL BOOST_SYMBOL_IMPORT
# define BOOST_A_DECL_VISIBLE BOOST_A_IMPORT
#endif

namespace boost { namespace alib {

   class BOOST_A_DECL myclass {/*...*/};
   class BOOST_A_DECL_VISIBLE myerror {/*...*/};

}}

Thoughts?

Regards


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