Specifying symbols, that have to be exported from shared library

Hi guys! Without any doubt, any shared library should export as less symbols as possible. First, this will decrease loading time of dynamic shared object. Second, it could eliminate some binary compatibility issues in the future. Boost libraries that are built as shared libraries (e.g., filesystem, datetime) explicitly specify symbols that have to be exported, but only when BOOST_HAS_DECLSPEC defined. So, only when building with toolsets msvc and borland (correct me if I'm wrong), this 'export' functionality is used. As we know, gcc allows not to export any symbol from shared library (if compiler flag -fvisibility=hidden is used) except ones declared with __attribute__((visibility("default"))), e.g.: class __attribute__((visibility("default"))) exported_class {//... As for me, it will be nice to exploit explicit symbols export in boost (if compiler allows this). In our software team, we use following macroses: SFI_DSO_EXPORT, SFI_DSO_IMPORT that are defined as: #if defined SFI_CC_GNUC # define SFI_DSO_EXPORT __attribute__((visibility("default"))) # define SFI_DSO_HIDE __attribute__((visibility("hidden"))) # define SFI_DSO_IMPORT #endif #if defined SFI_CC_MSVC # define SFI_DSO_EXPORT __declspec(dllexport) # define SFI_DSO_HIDE # define SFI_DSO_IMPORT __declspec(dllimport) #endif //etc... And some library use only them: //config.hpp #if defined SFI_ALIB_BUILD_SHLIB # define SFI_ALIB_DECL SFI_DSO_EXPORT #elif defined SFI_ALIB_USE_SHLIB # define SFI_ALIB_DECL SFI_DSO_IMPORT #else # define SFI_ALIB_DECL #endif Finally, here's the question. What do you think about having something like BOOST_DSO_EXPORT/*IMPORT in boost? Regards

Alexander Arhipenko wrote:
Boost libraries that are built as shared libraries (e.g., filesystem, datetime) explicitly specify symbols that have to be exported, but only when BOOST_HAS_DECLSPEC ... As we know, gcc allows not to export any symbol from shared library (if compiler flag -fvisibility=hidden is used) except ones declared with __attribute__((visibility("default"))), e.g.: .... Finally, here's the question. What do you think about having something like BOOST_DSO_EXPORT/*IMPORT in boost?
It would be nice. Care of work on a patch? - Volodya

On Wed, Jul 9, 2008 at 9:48 AM, Vladimir Prus <vladimir@codesourcery.com> wrote:
...
It would be nice. Care of work on a patch?
- Volodya
With great pleasure.
The patch against trunk attached. Some comments: 1. dso.hpp file is added to boost/config 2. all the libraries updated to export only specified symbols except: Boost.Python (because it has own gcc stuff) Boost.Serialization (because a lot of link failures appeared when running test cases) 3. The code was tested on gcc version 4.1.1 20070105 (Red Hat 4.1.1-52), i. e., test cases from boost/libs/LIB_NAME/test was run. No linker failures was experienced. Boost.MPI wasn't built and tested. Any comments? Regards

On Thu, 10 Jul 2008, Steven Watanabe wrote:
Alexander Arhipenko wrote:
Any comments? Could we have a more descriptive name than dso?
Dynamic Shared Objects? The dsohowto has a good writeup on the topic. - Daniel

Hi, Steven On Thu, Jul 10, 2008 at 7:37 PM, Steven Watanabe <watanabesj@gmail.com> wrote:
AMDG
Could we have a more descriptive name than dso?
In Christ, Steven Watanabe
I don't mind using more descriptive names, e.g.: BOOST_DSO_SYMBOL_EXPORT/IMPORT or BOOST_SHARED_LIBRARY_SYMBOL_EXPORT/IMPORT or simply BOOST_SYMBOL_EXPORT etc. I guess, this should be discussed with boost community Regards

On Thursday 10 July 2008 02:29:14 Alexander Arhipenko wrote:
On Wed, Jul 9, 2008 at 9:48 AM, Vladimir Prus <vladimir@codesourcery.com> wrote:
...
It would be nice. Care of work on a patch?
- Volodya
With great pleasure.
The patch against trunk attached. Some comments: 1. dso.hpp file is added to boost/config 2. all the libraries updated to export only specified symbols except: Boost.Python (because it has own gcc stuff) Boost.Serialization (because a lot of link failures appeared when running test cases) 3. The code was tested on gcc version 4.1.1 20070105 (Red Hat 4.1.1-52), i. e., test cases from boost/libs/LIB_NAME/test was run. No linker failures was experienced. Boost.MPI wasn't built and tested.
Any comments?
seems like a copy-paste bug in dso.hpp: +# define BOOST_DSO_EXPORT_EXCEPTION BOOST_DSO_EXPORT +# define BOOST_DSO_IMPORT_EXCEPTION BOOST_DSO_EXPORT ------------------------------------------------^^^^^^ cheers, sebastien. -- ################################### # Dr. Sebastien Binet # # Lawrence Berkeley National Lab. # # 1 Cyclotron Road # # Berkeley, CA 94720 # ###################################

Hi, Sebastien On Thu, Jul 10, 2008 at 7:53 PM, Sebastien Binet <hep.sebastien.binet@gmail.com> wrote:
seems like a copy-paste bug in dso.hpp:
+# define BOOST_DSO_EXPORT_EXCEPTION BOOST_DSO_EXPORT +# define BOOST_DSO_IMPORT_EXCEPTION BOOST_DSO_EXPORT ------------------------------------------------^^^^^^
cheers, sebastien.
It's not copy paste error, it was done by intention. Maybe you've mentioned, that BOOST_DSO_EXPORT(IMPORT)_EXCEPTION differs for msvc and gcc. I'll try to explain why we need special macro for exception export/import (and why it differs for msvc and gcc) on the sample. Let's assume I've created library My.Lib that links to Boost.Filesystem. My.Lib doesn't handle any Boost.Filesystem exception. It is supposed, that this will be done by My.Lib user. Finally, executable file User.Exe links My.Lib and Boost.Filesystem. Now consider use case: User.Exe calls function my::lib::function() exported from My.Lib. my::lib::function calls boost::filesystem::rename that can throw filesystem_error. So, filesystem_error are thrown from my::lib::function(). User.Exe catches filesystem_error, but mysterious thing happens: filesystem_error will never be caught! Because catch handler in User.Exe will look for typeinfo of filesystem_error in My.Lib that doesn't have it. So, My.Lib should export filesystem_error. All above related to gcc, look also at http://gcc.gnu.org/wiki/Visibility, exceptions section. Firstly I discovered this issue with VisualAge C++ compiler. I had shared library and following exported exception class: class Error : public std::exception. All was fine until I try to catch std::exception in binary that links that shared library :(. As a result, we exported std::exception from shared library too. So, designer of My.Lib library should decide, handle all the boost.filesystem exceptions and doesn't export them from My.Lib or not to handle and export. Regards

on Thu Jul 10 2008, "Alexander Arhipenko" <arhipjan-AT-gmail.com> wrote:
On Wed, Jul 9, 2008 at 9:48 AM, Vladimir Prus <vladimir@codesourcery.com> wrote:
...
It would be nice. Care of work on a patch?
- Volodya
With great pleasure.
The patch against trunk attached. Some comments: 1. dso.hpp file is added to boost/config 2. all the libraries updated to export only specified symbols except: Boost.Python (because it has own gcc stuff) Boost.Serialization (because a lot of link failures appeared when running test cases) 3. The code was tested on gcc version 4.1.1 20070105 (Red Hat 4.1.1-52), i. e., test cases from boost/libs/LIB_NAME/test was run. No linker failures was experienced. Boost.MPI wasn't built and tested.
Any comments?
Just one: patches tend to be more impactful when attached to Trac tickets: http://svn.boost.org ;-) -- Dave Abrahams BoostPro Computing http://www.boostpro.com

On Fri, Jul 11, 2008 at 5:11 PM, David Abrahams <dave@boostpro.com> wrote:
on Thu Jul 10 2008, "Alexander Arhipenko" <arhipjan-AT-gmail.com> wrote:
Any comments?
Just one: patches tend to be more impactful when attached to Trac tickets: http://svn.boost.org ;-)
I've submitted ticket (#2114) to trac and attached patch to it, see http://svn.boost.org/trac/boost/ticket/2114. Regards
participants (6)
-
Alexander Arhipenko
-
David Abrahams
-
dherring@ll.mit.edu
-
Sebastien Binet
-
Steven Watanabe
-
Vladimir Prus