Selectively exporting symbols for a library is a good thing. It keeps program startup times down and enforces the public API of a library. The Good is that it’s possible and even the default mode for Visual C++.
For whatever reason, the Visual C++ (or DLL?) designers decided that you have to declare your public functions with __declspec( dllexport ) when building the library and __declspec( dllimport ) when using it. What’s wrong with gcc’s visibility(“default”)?
All kind of fun ensues when you want to export explicit template instantiations with MSVC’s dualiton construct. Even more fun appears when you use static libraries.
The MSVC approach does not really work for static libraries. As far as I can tell, there are no exports for static libraries. Say you have a piece of code which you’ld like to share between different shared libraries without actually shipping this as a shared library as well. The fabric foundation in Equalizer is such an example, and right now this is ‘shared’ by compiling the relevant object three times – once for the client, server and admin library. Obviously this is not optimal since it increases the build time unnecessarily. Building fabric as a static library and linking it to these three shared libraries works fine with the GNU toolchain, but not with MSVC since it would require to manually specify all the public symbols when linking the DLL.
The implementation chosen by gcc is utterly useless for C++. Setting the default visibility to hidden requires to manually export the vtable of each class and all STL intantiations used – including the internal classes instantiated by the STL itself! While I can see how this implementation came into being, it is clearly designed for C code and not for C++. The vtable and STL are internals of the C++ implementation, developers should not need to care about them.
For now I have given up on using selective visibility with gcc, and only use explicit exports on Windows for Equalizer and other projects I’m working on. This makes sure that checkins will regularly break the Windows build. Hurray!
One can dream:
For the VC++ developers: Please provide a __declspec(dllvisible) which works also for re-exporting symbols from static libraries. Let the toolchain figure out the details.
For the GCC developers: Please make exporting symbols from C++ classes simpler. VC++ can do it, so it can’t be that hard!
The above is obviously a rant. I am fully aware that workarounds exist for all of the issues mentioned above. Implementing them in real build environments is more time consuming than it should be and than is feasible. If you know about simple fixes, please comment below.