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) set(ON_EXCEPT_EMSCRIPTEN ON)
endif() endif()
option(BUILD_STATIC_PIC "Build static libraries and plugins with position-independent code" ${ON_EXCEPT_EMSCRIPTEN}) 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_PLUGINS_STATIC "Build static plugins (default are dynamic)" OFF)
option(BUILD_TESTS "Build unit tests" 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) 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) if(BUILD_STATIC)
set(MAGNUM_BUILD_STATIC 1) set(MAGNUM_BUILD_STATIC 1)
if(BUILD_STATIC_UNIQUE_GLOBALS)
set(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS 1)
endif()
endif() endif()
# Check dependencies # 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 code. Enabled by default when building static libraries, disable if you
don't need this feature. On @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten" don't need this feature. On @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten"
this option is always off. 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 - `BUILD_PLUGINS_STATIC` --- Build plugins as static. By default, plugins are
built as dynamic. Independent of the `BUILD_STATIC` option to allow having built as dynamic. Independent of the `BUILD_STATIC` option to allow having
static libraries with dynamic plugins and vice versa. 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 executable location where possible and use hardcoded paths only if
explicitly specified. See @ref Trade::AbstractImporter::pluginSearchPaths() explicitly specified. See @ref Trade::AbstractImporter::pluginSearchPaths()
for more information. 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 @subsubsection changelog-latest-changes-audio Audio library

3
doc/cmake.dox

@ -308,6 +308,9 @@ are also available as preprocessor variables if including
included included
- `MAGNUM_BUILD_STATIC` --- Defined if compiled as static libraries. Default - `MAGNUM_BUILD_STATIC` --- Defined if compiled as static libraries. Default
are shared libraries. 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 - `MAGNUM_TARGET_GL` --- Defined if compiled with OpenGL interoperability
enabled enabled
- `MAGNUM_TARGET_GLES` --- Defined if compiled for OpenGL ES - `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 # MAGNUM_BUILD_DEPRECATED - Defined if compiled with deprecated APIs
# included # included
# MAGNUM_BUILD_STATIC - Defined if compiled as static libraries # 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_GL - Defined if compiled with OpenGL interop
# MAGNUM_TARGET_GLES - Defined if compiled for OpenGL ES # MAGNUM_TARGET_GLES - Defined if compiled for OpenGL ES
# MAGNUM_TARGET_GLES2 - Defined if compiled for OpenGL ES 2.0 # MAGNUM_TARGET_GLES2 - Defined if compiled for OpenGL ES 2.0
@ -249,6 +251,7 @@ string(REGEX REPLACE "\n" ";" _magnumConfigure "${_magnumConfigure}")
set(_magnumFlags set(_magnumFlags
BUILD_DEPRECATED BUILD_DEPRECATED
BUILD_STATIC BUILD_STATIC
BUILD_STATIC_UNIQUE_GLOBALS
TARGET_GL TARGET_GL
TARGET_GLES TARGET_GLES
TARGET_GLES2 TARGET_GLES2

13
src/Magnum/Audio/Context.cpp

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

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

@ -42,9 +42,19 @@ GlobalStateAcrossLibrariesALTest::GlobalStateAcrossLibrariesALTest() {
} }
void GlobalStateAcrossLibrariesALTest::test() { 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; Context context;
CORRADE_VERIFY(Context::hasCurrent()); 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" #include "Magnum/GL/Implementation/TransformFeedbackState.h"
#endif #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" #include "Magnum/Implementation/WindowsWeakSymbol.h"
#endif #endif
@ -500,7 +500,7 @@ Containers::ArrayView<const Extension> Extension::extensions(Version version) {
CORRADE_INTERNAL_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ 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 /* (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) */ (except for Windows, where we do extern "C" so this doesn't matter) */
namespace { namespace {
@ -509,7 +509,7 @@ namespace {
#ifdef CORRADE_BUILD_MULTITHREADED #ifdef CORRADE_BUILD_MULTITHREADED
CORRADE_THREAD_LOCAL CORRADE_THREAD_LOCAL
#endif #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 /* 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 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. it's apparently enough to just export, macOS needs the weak attribute.
@ -523,7 +523,7 @@ CORRADE_VISIBILITY_EXPORT
#endif #endif
Context* currentContext = nullptr; Context* currentContext = nullptr;
#if !defined(MAGNUM_BUILD_STATIC) || defined(CORRADE_TARGET_WINDOWS) #if !defined(MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS) || defined(CORRADE_TARGET_WINDOWS)
} }
#endif #endif
@ -535,7 +535,7 @@ Context* currentContext = nullptr;
pick up the same symbol of the final exe independently of the DLL it was 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 called from. To avoid #ifdef hell in code below, the currentContext is
redefined to return a value from this uniqueness-ensuring function. */ 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. /* 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. */ I don't care, I only need an unmangled name to look up later at runtime. */
#ifdef CORRADE_TARGET_CLANG_CL #ifdef CORRADE_TARGET_CLANG_CL

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

@ -41,8 +41,18 @@ GlobalStateAcrossLibrariesGLTest::GlobalStateAcrossLibrariesGLTest() {
} }
void GlobalStateAcrossLibrariesGLTest::test() { 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_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 #define MAGNUM_BUILD_STATIC
#undef 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 #ifdef MAGNUM_BUILD_DEPRECATED
/** @brief Multi-threaded build /** @brief Multi-threaded build
* @m_deprecated_since{2019,10} Use @ref CORRADE_BUILD_MULTITHREADED instead. * @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_DEPRECATED
#cmakedefine MAGNUM_BUILD_STATIC #cmakedefine MAGNUM_BUILD_STATIC
#cmakedefine MAGNUM_BUILD_STATIC_UNIQUE_GLOBALS
#cmakedefine MAGNUM_TARGET_GL #cmakedefine MAGNUM_TARGET_GL
#cmakedefine MAGNUM_TARGET_GLES #cmakedefine MAGNUM_TARGET_GLES
#cmakedefine MAGNUM_TARGET_GLES2 #cmakedefine MAGNUM_TARGET_GLES2

Loading…
Cancel
Save