-
Notifications
You must be signed in to change notification settings - Fork 154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Should boost force symbol visibility if built as a static lib? #243
Comments
Confirmed, but this is an issue with throw_exception and should be reported here: https://github.com/boostorg/throw_exception. That header should be using BOOST_SYMBOL_VISIBLE rather than the push/pop's. I would guess that their workaround pre-dates the introduction of BOOST_SYMBOL_VISIBLE. |
I've reported it there and proposed a small patch to replace the push/pops with BOOST_SYMBOL_VISIBLE. However, that only seems to be half the solution, since BOOST_SYMBOL_VISIBLE is always set to attribute((visibility("default"))) in config/compiler/gcc.hpp if GNUC >= 4, regardless of whether the boost build system is building a shared library or not. In the end I need the ability to build my boost-using shared library with -fvisibility=hidden and -fvisibility=hidden-inlines, without individual symbols from Boost forcing themselves out of my interface. I guess somehow or other, that implies adding an extra condition before setting BOOST_SYMBOL_VISIBLE to whatever the compiler needs. A possibility could be a BOOST_INTERFACE_VISIBLE macro that either Boost itself can set when Boost is building a shared library, or that the user can set if she uses boost classes as part of the interface of her own shared library. What do you think? |
Ah my bad, we have an issue here, because there are 2 conflicting use cases:
I'm not sure that we've ever really supported the second case - except as a sort of accident by having code that's not marked up. I'll raise this on the mailing list, it's probably better to try and fix boost-wide (if we can) rather than each library doing it's own thing. |
Any feedback on this? |
I have an idea, but I'm working on another bug report right now.... nag me if I'm not back to you shortly... |
My suggestion was going to be a macro - say BOOST_DISABLE_VISIBLE_SYMBOLS - which when set by the user would result in the BOOST_SYMBOL_* macros being set to nothing. That would then allow you to hide everything. I have a suspicion that some things (exception classes and some of the serialization lib) will not then work correctly, but I'm not sure? |
I don't think this is a good idea. This may break exceptions and RTTI support. Boost.Log relies on this, for example. Other libraries, probably, too (Boost.Any comes to mind). One example where making all symbols hidden may make sense is when a user builds a monolithic executable that does not use any other shared libraries, or uses them without passing any Boost-related types, including exceptions. Those cases can be covered by linker scripts, there's no need to change Boost for that. The particular issue with Boost.ASIO though should be reported to upstream ASIO. I see no reason why it should mark all of its symbols visible (see here and here). But it may need to mark so exceptions, selectively. This is not a Boost.Config issue and changing Boost.Config will not fix Boost.ASIO and it will break other libraries. |
If you are wanting to hide all internal usage of Boost, and you are:
Then it is probably safe (and correct) to disable Boost symbol visibility across the board. Violating any one of those four constraints would break things, however. |
I meet all four criteria above. Question is how to force all the symbols private? |
Use linker scripts. |
I came accross exactly the same problem, where our dynamic library is one of huge amount of custom libraries in multi plug-in environment. Disabling ASIO symbols with macro switch partially helped, as all symbols in header like boost system still use BOOST_SYMBOL_VISIBLE and this caused to crash in my case by throwing an exception from asio. I guess this case is quite uncommon, as in my example there are 100 dynamic libs which work in independent way, and are not interacting with each other at all. That being said I think it would be very helpfull if there would be any way to simply diable BOOST_SYMBOL_VISIBLE by overriding it to nothing during compilation. |
that only works on platforms which supports those. What's wrong with just adding a in addition, doing this at the linker stage prevents compiler optimizations that could be done based on symbol visibility. |
See #441 for a patch |
I'm consuming boost::asio as a static library in a project that is delivered as a shared library. To avoid conflicts in clients, I try to hide all symbols originating from my dependencies by linking with -Wl,--exclude-libs,ALL.
To my surprise, this does not work for boost::asio. A little research showed that at some point it was deemed a good idea to force default visibility on exception typeinfo and support classes for printing the exceptions from boost, see eg. https://svn.boost.org/trac10/ticket/4594 which proposed a #pragma visibility push default, only conditional on the compiler. So regardless of whether boost is built as a static or a dynamic library, the symbols get marked with default visibility on GCC.
And now I wonder if this is really the correct policy, or if boost (and any library) should rather refrain from explicitly setting visibility attributes when building a static library. Doesn't that make more sense?
Right now I have a nasty symbol leak that causes conflicts in my clients using a different version of asio. Updated: the problem has been reported before, along with a possible solution, see https://svn.boost.org/trac10/ticket/12722.
N.B.: moved here from boostorg/asio#145
The text was updated successfully, but these errors were encountered: