diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 5db03e2f..cb66e769 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -60,12 +60,10 @@ struct type_info { bool default_holder : 1; }; -// Store the static internals pointer in a version-specific function so that we're guaranteed it -// will be distinct for modules compiled for different pybind11 versions. Without this, some -// compilers (i.e. gcc) can use the same static pointer storage location across different .so's, -// even though the `get_internals()` function itself is local to each shared object. -template -internals *&get_internals_ptr() { static internals *internals_ptr = nullptr; return internals_ptr; } +PYBIND11_UNSHARED_STATIC_LOCALS PYBIND11_NOINLINE inline internals *&get_internals_ptr() { + static internals *internals_ptr = nullptr; + return internals_ptr; +} PYBIND11_NOINLINE inline internals &get_internals() { internals *&internals_ptr = get_internals_ptr(); diff --git a/include/pybind11/common.h b/include/pybind11/common.h index 240f6d8e..518e2456 100644 --- a/include/pybind11/common.h +++ b/include/pybind11/common.h @@ -68,6 +68,16 @@ # endif #endif +// Attribute macro for a function containing one or more static local variables that mustn't share +// the variable across shared objects (for example, because the value might be incompatible for +// modules compiled under different pybind versions). This is required under g++ (depending on the +// specific compiler and linker options), and won't hurt under gcc-compatible compilers: +#if defined(__GNUG__) +# define PYBIND11_UNSHARED_STATIC_LOCALS __attribute__ ((visibility("hidden"))) +#else +# define PYBIND11_UNSHARED_STATIC_LOCALS +#endif + #if defined(_MSC_VER) # define PYBIND11_NOINLINE __declspec(noinline) #else