diff --git a/doc/changelog.dox b/doc/changelog.dox index bbc53c673..e5061e1ab 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -293,6 +293,10 @@ See also: - @ref Image::data(), @ref CompressedImage::data() and @ref Trade::ImageData::data() called on a r-value now return @ref Corrade::Containers::Array instead of being deleted +- Global state used by @ref GL::Context and @ref Audio::Context is no longer + duplicated when Magnum is built statically and linked to more than one + dynamic library or executable. Currently that holds only for Linux and + macOS, Windows support will come next. @subsubsection changelog-latest-changes-animation Animation library diff --git a/src/Magnum/Audio/Context.cpp b/src/Magnum/Audio/Context.cpp index b6f9dcd89..f14113e82 100644 --- a/src/Magnum/Audio/Context.cpp +++ b/src/Magnum/Audio/Context.cpp @@ -113,11 +113,31 @@ std::vector Context::deviceSpecifierStrings() { return list; } +#ifndef MAGNUM_BUILD_STATIC +/* (Of course) can't be in an unnamed namespace in order to export it below */ namespace { - /* Unlike GL, this isn't thread-local. Would need to implement - ALC_EXT_thread_local_context first */ - Context* currentContext = nullptr; +#endif + +/* Unlike GL, this isn't thread-local. Would need to implement + ALC_EXT_thread_local_context first */ +#if defined(MAGNUM_BUILD_STATIC) && !defined(CORRADE_TARGET_WINDOWS) +/* On static builds that get linked to multiple shared libraries and then used + in a single app we want to ensure there's just one global symbol. On Linux + it's apparently enough to just export, macOS needs the weak attribute. + Windows not handled yet, as it needs a workaround using DllMain() and + GetProcAddress(). */ +CORRADE_VISIBILITY_EXPORT + #ifdef __GNUC__ + __attribute__((weak)) + #else + /* uh oh? the test will fail, probably */ + #endif +#endif +Context* currentContext = nullptr; + +#ifndef MAGNUM_BUILD_STATIC } +#endif bool Context::hasCurrent() { return currentContext; } diff --git a/src/Magnum/Audio/Test/GlobalStateAcrossLibrariesALTest.cpp b/src/Magnum/Audio/Test/GlobalStateAcrossLibrariesALTest.cpp index b6d96ee08..78ac07a7c 100644 --- a/src/Magnum/Audio/Test/GlobalStateAcrossLibrariesALTest.cpp +++ b/src/Magnum/Audio/Test/GlobalStateAcrossLibrariesALTest.cpp @@ -44,7 +44,12 @@ GlobalStateAcrossLibrariesALTest::GlobalStateAcrossLibrariesALTest() { void GlobalStateAcrossLibrariesALTest::test() { Context context; CORRADE_VERIFY(Context::hasCurrent()); - CORRADE_COMPARE(currentContextInALibrary(), &context); + { + #ifdef CORRADE_TARGET_WINDOWS + CORRADE_EXPECT_FAIL("Deduplication of global data across shared libraries isn't implemented on Windows yet."); + #endif + CORRADE_COMPARE(currentContextInALibrary(), &context); + } } }}}} diff --git a/src/Magnum/GL/Context.cpp b/src/Magnum/GL/Context.cpp index 593c9fe3b..8919c0cc2 100644 --- a/src/Magnum/GL/Context.cpp +++ b/src/Magnum/GL/Context.cpp @@ -466,12 +466,32 @@ Containers::ArrayView Extension::extensions(Version version) { CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ } +#ifndef MAGNUM_BUILD_STATIC +/* (Of course) can't be in an unnamed namespace in order to export it below */ namespace { - #ifdef CORRADE_BUILD_MULTITHREADED - CORRADE_THREAD_LOCAL +#endif + +#ifdef CORRADE_BUILD_MULTITHREADED +CORRADE_THREAD_LOCAL +#endif +#if defined(MAGNUM_BUILD_STATIC) && !defined(CORRADE_TARGET_WINDOWS) +/* On static builds that get linked to multiple shared libraries and then used + in a single app we want to ensure there's just one global symbol. On Linux + it's apparently enough to just export, macOS needs the weak attribute. + Windows not handled yet, as it needs a workaround using DllMain() and + GetProcAddress(). */ +CORRADE_VISIBILITY_EXPORT + #ifdef __GNUC__ + __attribute__((weak)) + #else + /* uh oh? the test will fail, probably */ #endif - Context* currentContext = nullptr; +#endif +Context* currentContext = nullptr; + +#ifndef MAGNUM_BUILD_STATIC } +#endif bool Context::hasCurrent() { return currentContext; } diff --git a/src/Magnum/GL/Test/GlobalStateAcrossLibrariesGLTest.cpp b/src/Magnum/GL/Test/GlobalStateAcrossLibrariesGLTest.cpp index 70b488a53..da26ad784 100644 --- a/src/Magnum/GL/Test/GlobalStateAcrossLibrariesGLTest.cpp +++ b/src/Magnum/GL/Test/GlobalStateAcrossLibrariesGLTest.cpp @@ -42,7 +42,12 @@ GlobalStateAcrossLibrariesGLTest::GlobalStateAcrossLibrariesGLTest() { void GlobalStateAcrossLibrariesGLTest::test() { CORRADE_VERIFY(GL::Context::hasCurrent()); - CORRADE_COMPARE(currentContextInALibrary(), &GL::Context::current()); + { + #ifdef CORRADE_TARGET_WINDOWS + CORRADE_EXPECT_FAIL("Deduplication of global data across shared libraries isn't implemented on Windows yet."); + #endif + CORRADE_COMPARE(currentContextInALibrary(), &GL::Context::current()); + } } }}}}