-
Notifications
You must be signed in to change notification settings - Fork 441
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
Apply MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS for the flextGL globals as well #636
Comments
Hi, thanks for a very detailed report! There's two different things happening here. One is that the symbol isn't exported if Magnum is built as static, which is how it should be (no other "usual" symbols are exported from static builds either). So if you have a static build of Magnum linked into a shared library, the symbols are reachable just from the static library itself and not from outside, i.e. from another shared lib or an executable. Using Magnum from there means linking to its static libraries again, which is what you did (and if you wouldn't, the build would end with a linker error). The consequence of linking the static library to two shared libraries is that its code gets duplicated in both shared libraries, which is wasteful from a code size perspective, but other than that it's a valid usage. For the most part. The other thing is that, unfortunately, even after I tried very hard to avoid mutable global state, there's still some left, in this particular case for the current GL context and the GL entrypoints. (Another mutable global state is debug/error output redirection or static plugin management in the plugin manager, the in-progress Vulkan wrapper OTOH doesn't rely on any global state.) Apart from this global state needing to be thread-local to avoid races, the main problem is that the globals get duplicated when you link the same static library to two different shared libraries, like you do in your case. So one shared library sees a global that's different from what the other sees, thus if a There's various platform-specific ways to solve this, what the other globals rely on is What didn't get this "global deduplication" treatment so far, and what #453 mentions in particular, is this But maybe being a bit slow is still better than causing nasty segfaults, heh. I'll think about this. That it did work for you with just exporting the symbol is just a coincidence, I fear. With a slightly different linking order or a more complex library setup it can still result in a different global being picked for every shared lib, so there really needs to be something explicitly for ensuring the deduplication. Any other ideas? :) |
Wow, thanks for this very detailed and in-depth answer! I learned a lot of things. I thought I had the visibility thing figured out but definitely did not think about the overhead when sharing global state. I guess I will switch to a build with shared libraries. |
I think one solution to your use case would be a static build of Magnum with all symbols exported, that gets linked only to one of your shared libraries, and the rest of the project / other shared libraries would then link to that shared library, not to (static) Magnum. Because linking to static Magnum would cause the duplicate globals issue to appear again. This could be doable if I would provide a way to supply a custom value of Generally, linking static libraries to shared ones is a valid use case for example if you have a middleware product that ships as a shared library, and you don't want its internals to be known, or used from outside. Then, if a user of given shared library would want to use Magnum on their end as well, they'd have to build its own and link to it again. The two instances (assuming But besides this one use case, if it's desired to have Magnum used across shared libraries, the best is to either have it build as shared as well, or as static, but limit your code to just one shared library / just one executable. Lot less headaches that way :) In any case, I'll attempt to fix the |
I think I'll go with the shared library option, because we'd want others to be able to look at the internals and extend functionality so it makes sense Cheers, thanks for answering my questions and enlightening me :) |
Hi!
In the following line in flextGL.h, the
flextGL
global variable has the attributeFLEXTGL_EXPORT
which is the emptyCORRADE_VISIBILITY_STATIC
when the build is static (hence the symbol is hidden, following the-fvisibility
compile flag):magnum/src/MagnumExternal/OpenGL/GL/flextGL.h
Line 2629 in b141901
But since it's a global and we could make a shared library against a static build of Magnum, shouldn't we check for
MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS
just like inGL/Context.cpp
?magnum/src/Magnum/GL/Context.cpp
Lines 672 to 684 in b141901
I tried the following change where the global's visibility is set to default when we require unique globals:
Or maybe the
FLEXTGL_EXPORT
macro should be changed? For me, the above fixed a segmentation fault issue I was having when instantiating a custom shader defined in my shared library (linked against a static build of Magnum, working on Ubuntu with clang). I saw that there's a mention of FlextGL symbols in #453.The text was updated successfully, but these errors were encountered: