Browse Source

Introduce a BUILD_STATIC_UNIQUE_GLOBALS option.

Same as in Corrade. Because BUILD_STATIC is independent between Corrade
and Magnum this option is also independent -- the corner cases and bad
interactions would be otherwise too complex to handle (e.g., in case of
a dynamic Corrade and static Magnum it would be impossible to enable
this option for Magnum etc etc).
pull/438/head
Vladimír Vondruš 6 years ago
parent
commit
9c14d8e354
  1. 4
      CMakeLists.txt
  2. 5
      doc/building.dox
  3. 2
      doc/changelog.dox
  4. 3
      doc/cmake.dox
  5. 3
      modules/FindMagnum.cmake
  6. 13
      src/Magnum/Audio/Context.cpp
  7. 12
      src/Magnum/Audio/Test/GlobalStateAcrossLibrariesALTest.cpp
  8. 10
      src/Magnum/GL/Context.cpp
  9. 12
      src/Magnum/GL/Test/GlobalStateAcrossLibrariesGLTest.cpp
  10. 10
      src/Magnum/Magnum.h
  11. 1
      src/Magnum/configure.h.cmake

4
CMakeLists.txt

@ -186,6 +186,7 @@ else()
set(ON_EXCEPT_EMSCRIPTEN ON)
endif()
option(BUILD_STATIC_PIC "Build static libraries and plugins with position-independent code" ${ON_EXCEPT_EMSCRIPTEN})
cmake_dependent_option(BUILD_STATIC_UNIQUE_GLOBALS "Build static libraries with globals unique across shared libraries" ${ON_EXCEPT_EMSCRIPTEN} "BUILD_STATIC" OFF)
option(BUILD_PLUGINS_STATIC "Build static plugins (default are dynamic)" OFF)
option(BUILD_TESTS "Build unit tests" OFF)
cmake_dependent_option(BUILD_GL_TESTS "Build unit tests for OpenGL code" OFF "BUILD_TESTS;TARGET_GL" OFF)
@ -219,6 +220,9 @@ endif()
if(BUILD_STATIC)
set(MAGNUM_BUILD_STATIC 1)
if(BUILD_STATIC_UNIQUE_GLOBALS)
set(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS 1)
endif()
endif()
# Check dependencies

5
doc/building.dox

@ -630,6 +630,11 @@ Options controlling the build:
code. Enabled by default when building static libraries, disable if you
don't need this feature. On @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten"
this option is always off.
- `BUILD_STATIC_UNIQUE_GLOBALS` --- Build static libraries in a way that
keeps their globals unique even across different shared libraries. Enabled
by default for static builds. May introduce additional overhead on some
platforms, disable if you will only link static libraries to one final
executable and won't use any dynamic plugins.
- `BUILD_PLUGINS_STATIC` --- Build plugins as static. By default, plugins are
built as dynamic. Independent of the `BUILD_STATIC` option to allow having
static libraries with dynamic plugins and vice versa.

2
doc/changelog.dox

@ -317,6 +317,8 @@ See also:
executable location where possible and use hardcoded paths only if
explicitly specified. See @ref Trade::AbstractImporter::pluginSearchPaths()
for more information.
- Added an ability to disable unique globals across shared libraries using
@ref MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS on static builds that don't need it
@subsubsection changelog-latest-changes-audio Audio library

3
doc/cmake.dox

@ -308,6 +308,9 @@ are also available as preprocessor variables if including
included
- `MAGNUM_BUILD_STATIC` --- Defined if compiled as static libraries. Default
are shared libraries.
- `MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS` --- Defined if static libraries keep
their globals unique even across different shared libraries. Enabled by
default for static builds.
- `MAGNUM_TARGET_GL` --- Defined if compiled with OpenGL interoperability
enabled
- `MAGNUM_TARGET_GLES` --- Defined if compiled for OpenGL ES

3
modules/FindMagnum.cmake

@ -126,6 +126,8 @@
# MAGNUM_BUILD_DEPRECATED - Defined if compiled with deprecated APIs
# included
# MAGNUM_BUILD_STATIC - Defined if compiled as static libraries
# MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS - Defined if static libraries keep the
# globals unique even across different shared libraries
# MAGNUM_TARGET_GL - Defined if compiled with OpenGL interop
# MAGNUM_TARGET_GLES - Defined if compiled for OpenGL ES
# MAGNUM_TARGET_GLES2 - Defined if compiled for OpenGL ES 2.0
@ -249,6 +251,7 @@ string(REGEX REPLACE "\n" ";" _magnumConfigure "${_magnumConfigure}")
set(_magnumFlags
BUILD_DEPRECATED
BUILD_STATIC
BUILD_STATIC_UNIQUE_GLOBALS
TARGET_GL
TARGET_GLES
TARGET_GLES2

13
src/Magnum/Audio/Context.cpp

@ -41,7 +41,7 @@
#include "Magnum/Audio/Extensions.h"
#if defined(CORRADE_TARGET_WINDOWS) && defined(MAGNUM_BUILD_STATIC) && !defined(CORRADE_TARGET_WINDOWS_RT)
#if defined(CORRADE_TARGET_WINDOWS) && defined(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS) && !defined(CORRADE_TARGET_WINDOWS_RT)
#include "Magnum/Implementation/WindowsWeakSymbol.h"
#endif
@ -119,7 +119,7 @@ std::vector<std::string> Context::deviceSpecifierStrings() {
return list;
}
#if !defined(MAGNUM_BUILD_STATIC) || defined(CORRADE_TARGET_WINDOWS)
#if !defined(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS) || defined(CORRADE_TARGET_WINDOWS)
/* (Of course) can't be in an unnamed namespace in order to export it below
(except for Windows, where we do extern "C" so this doesn't matter) */
namespace {
@ -127,8 +127,9 @@ namespace {
/* Unlike GL, this isn't thread-local. Would need to implement
ALC_EXT_thread_local_context first */
#if !defined(MAGNUM_BUILD_STATIC) || (defined(MAGNUM_BUILD_STATIC) && !defined(CORRADE_TARGET_WINDOWS))
#ifdef MAGNUM_BUILD_STATIC
/* What the hell is going on here with the #ifdefs?! */
#if !defined(MAGNUM_BUILD_STATIC) || !defined(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS) || (defined(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS) && !defined(CORRADE_TARGET_WINDOWS))
#ifdef MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS
/* 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.
@ -152,7 +153,7 @@ extern "C" {
}
#endif
#if !defined(MAGNUM_BUILD_STATIC) || defined(CORRADE_TARGET_WINDOWS)
#if !defined(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS) || defined(CORRADE_TARGET_WINDOWS)
}
#endif
@ -161,7 +162,7 @@ extern "C" {
pick up the same symbol of the final exe independently of the DLL it was
called from. To avoid #ifdef hell in code below, the currentContext is
redefined to return a value from this uniqueness-ensuring function. */
#if defined(CORRADE_TARGET_WINDOWS) && defined(MAGNUM_BUILD_STATIC) && !defined(CORRADE_TARGET_WINDOWS_RT)
#if defined(CORRADE_TARGET_WINDOWS) && defined(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS) && !defined(CORRADE_TARGET_WINDOWS_RT)
namespace {
Context*& windowsCurrentContext() {

12
src/Magnum/Audio/Test/GlobalStateAcrossLibrariesALTest.cpp

@ -42,9 +42,19 @@ GlobalStateAcrossLibrariesALTest::GlobalStateAcrossLibrariesALTest() {
}
void GlobalStateAcrossLibrariesALTest::test() {
#if defined(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS) && !defined(MAGNUM_BUILD_STATIC)
CORRADE_VERIFY(!"MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS enabled but MAGNUM_BUILD_STATIC not");
#endif
Context context;
CORRADE_VERIFY(Context::hasCurrent());
CORRADE_COMPARE(currentContextInALibrary(), &context);
{
#ifndef MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS
CORRADE_EXPECT_FAIL("MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS not enabled.");
#endif
CORRADE_COMPARE(currentContextInALibrary(), &context);
}
}
}}}}

10
src/Magnum/GL/Context.cpp

@ -65,7 +65,7 @@
#include "Magnum/GL/Implementation/TransformFeedbackState.h"
#endif
#if defined(CORRADE_TARGET_WINDOWS) && defined(MAGNUM_BUILD_STATIC) && !defined(CORRADE_TARGET_WINDOWS_RT)
#if defined(CORRADE_TARGET_WINDOWS) && defined(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS) && !defined(CORRADE_TARGET_WINDOWS_RT)
#include "Magnum/Implementation/WindowsWeakSymbol.h"
#endif
@ -500,7 +500,7 @@ Containers::ArrayView<const Extension> Extension::extensions(Version version) {
CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
}
#if !defined(MAGNUM_BUILD_STATIC) || defined(CORRADE_TARGET_WINDOWS)
#if !defined(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS) || defined(CORRADE_TARGET_WINDOWS)
/* (Of course) can't be in an unnamed namespace in order to export it below
(except for Windows, where we do extern "C" so this doesn't matter) */
namespace {
@ -509,7 +509,7 @@ namespace {
#ifdef CORRADE_BUILD_MULTITHREADED
CORRADE_THREAD_LOCAL
#endif
#if defined(MAGNUM_BUILD_STATIC) && !defined(CORRADE_TARGET_WINDOWS)
#if defined(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS) && !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.
@ -523,7 +523,7 @@ CORRADE_VISIBILITY_EXPORT
#endif
Context* currentContext = nullptr;
#if !defined(MAGNUM_BUILD_STATIC) || defined(CORRADE_TARGET_WINDOWS)
#if !defined(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS) || defined(CORRADE_TARGET_WINDOWS)
}
#endif
@ -535,7 +535,7 @@ Context* currentContext = nullptr;
pick up the same symbol of the final exe independently of the DLL it was
called from. To avoid #ifdef hell in code below, the currentContext is
redefined to return a value from this uniqueness-ensuring function. */
#if defined(CORRADE_TARGET_WINDOWS) && defined(MAGNUM_BUILD_STATIC) && !defined(CORRADE_TARGET_WINDOWS_RT)
#if defined(CORRADE_TARGET_WINDOWS) && defined(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS) && !defined(CORRADE_TARGET_WINDOWS_RT)
/* Clang-CL complains that the function has a return type incompatible with C.
I don't care, I only need an unmangled name to look up later at runtime. */
#ifdef CORRADE_TARGET_CLANG_CL

12
src/Magnum/GL/Test/GlobalStateAcrossLibrariesGLTest.cpp

@ -41,8 +41,18 @@ GlobalStateAcrossLibrariesGLTest::GlobalStateAcrossLibrariesGLTest() {
}
void GlobalStateAcrossLibrariesGLTest::test() {
#if defined(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS) && !defined(MAGNUM_BUILD_STATIC)
CORRADE_VERIFY(!"MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS enabled but MAGNUM_BUILD_STATIC not");
#endif
CORRADE_VERIFY(GL::Context::hasCurrent());
CORRADE_COMPARE(currentContextInALibrary(), &GL::Context::current());
{
#ifndef MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS
CORRADE_EXPECT_FAIL("MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS not enabled.");
#endif
CORRADE_COMPARE(currentContextInALibrary(), &GL::Context::current());
}
}
}}}}

10
src/Magnum/Magnum.h

@ -66,6 +66,16 @@ Defined if built as static libraries. Default are shared libraries.
#define MAGNUM_BUILD_STATIC
#undef MAGNUM_BUILD_STATIC
/**
@brief Static library build with globals unique across shared libraries
@m_since_latest
Enabled by default in a static build.
@see @ref building, @ref cmake
*/
#define MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS
#undef MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS
#ifdef MAGNUM_BUILD_DEPRECATED
/** @brief Multi-threaded build
* @m_deprecated_since{2019,10} Use @ref CORRADE_BUILD_MULTITHREADED instead.

1
src/Magnum/configure.h.cmake

@ -27,6 +27,7 @@
#cmakedefine MAGNUM_BUILD_DEPRECATED
#cmakedefine MAGNUM_BUILD_STATIC
#cmakedefine MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS
#cmakedefine MAGNUM_TARGET_GL
#cmakedefine MAGNUM_TARGET_GLES
#cmakedefine MAGNUM_TARGET_GLES2

Loading…
Cancel
Save