cginternals/cmake-init

Set CXX_VISIBILITY_PRESET to "default" for AppleClang

j-o opened this issue · 2 comments

j-o commented

AppleClang (and clang?) handles RTTI for template instantiations a little different than MSVC and GCC:
With visibility "hidden", a template instantiation in library A is a different type than the exact same template instantiation in library B that links against A. That means, that dynamic_casts between those types fail with AppleClang, but not with MSVC or GCC. With visibility "default", it works.

An example is the gloperate::Loader<T>. During component registration, e.g., gloperate::Loader<Texture> is instantiated within the gloperate-qt-loaders plugin (soon to be gloperate-qt). Loader objects created by the ResourceManager have this type. When an application then calls ResourceManager::load<Texture>, gloperate::Loader<Texture> is instantiated again within the application. As both are different types according to AppleClangs RTTI, the dynamic_cast used to find a loader of the correct type always fails.

A "clean" solution might be to explicitly export all those template instantiations; however, (I think) @scheibel and I both tried it and could not get it to work. Until someone actually manages that, I propose to set the cmake CXX_VISIBILITY_PRESET to "default" for AppleClang, as this is a very subtle bug that is hard to find.

Does anybody know, whether this affects clang as well?

Yes, I also propose to set the visibility to default for the AppleClang.
I have to test if the regular clang is affected, too.

I opened PR #61 that should handle this (surprisingly correct) behavior of clang.
It seems that both clang and AppleClang are affected.