diff --git a/CMakeLists.txt b/CMakeLists.txt index 51a17d9aa5..842b59fbe9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,6 +91,9 @@ if(NOT (CMAKE_VERSION VERSION_LESS 3.0)) # CMake >= 3.0 $ $) target_compile_options(pybind11 INTERFACE $) + if(NOT MSVC) + target_compile_options(pybind11 INTERFACE -fvisibility=hidden) + endif() add_library(module INTERFACE) add_library(pybind11::module ALIAS module) diff --git a/docs/advanced/misc.rst b/docs/advanced/misc.rst index 8751faf671..6d8cfc9b8b 100644 --- a/docs/advanced/misc.rst +++ b/docs/advanced/misc.rst @@ -135,22 +135,16 @@ has been executed: Naturally, both methods will fail when there are cyclic dependencies. -Note that compiling code which has its default symbol visibility set to -*hidden* (e.g. via the command line flag ``-fvisibility=hidden`` on GCC/Clang) can interfere with the -ability to access types defined in another extension module. Workarounds -include changing the global symbol visibility (not recommended, because it will -lead unnecessarily large binaries) or manually exporting types that are -accessed by multiple extension modules: +Note that pybind11 code compiled with hidden-by-default symbol visibility (e.g. +via the command line flag ``-fvisibility=hidden`` on GCC/Clang), which is +required proper pybind11 functionality, can interfere with the ability to +access types defined in another extension module. Working around this requires +manually exporting types that are accessed by multiple extension modules; +pybind11 provides a macro to do just this: .. code-block:: cpp - #ifdef _WIN32 - # define EXPORT_TYPE __declspec(dllexport) - #else - # define EXPORT_TYPE __attribute__ ((visibility("default"))) - #endif - - class EXPORT_TYPE Dog : public Animal { + class PYBIND11_EXPORT Dog : public Animal { ... }; diff --git a/docs/compiling.rst b/docs/compiling.rst index 91e65df3db..90b3829523 100644 --- a/docs/compiling.rst +++ b/docs/compiling.rst @@ -74,13 +74,15 @@ removes this target from the default build (see CMake docs for details). Since pybind11 is a template library, ``pybind11_add_module`` adds compiler flags to ensure high quality code generation without bloat arising from long -symbol names and duplication of code in different translation units. The -additional flags enable LTO (Link Time Optimization), set default visibility -to *hidden* and strip unneeded symbols. See the :ref:`FAQ entry ` -for a more detailed explanation. These optimizations are never applied in -``Debug`` mode. If ``NO_EXTRAS`` is given, they will always be disabled, even -in ``Release`` mode. However, this will result in code bloat and is generally -not recommended. +symbol names and duplication of code in different translation units. It +sets default visibility to *hidden*, which is required for some pybind11 +features and functionality when attempting to load multiple pybind11 modules +compiled under different pybind11 versions. It also adds additional flags +enabling LTO (Link Time Optimization) and strip unneeded symbols. See the +:ref:`FAQ entry ` for a more detailed explanation. These +latter optimizations are never applied in ``Debug`` mode. If ``NO_EXTRAS`` is +given, they will always be disabled, even in ``Release`` mode. However, this +will result in code bloat and is generally not recommended. As stated above, LTO is enabled by default. Some newer compilers also support different flavors of LTO such as `ThinLTO`_. Setting ``THIN_LTO`` will cause @@ -181,9 +183,8 @@ to an independently constructed (through ``add_library``, not flags (i.e. this is up to you). These include Link Time Optimization (``-flto`` on GCC/Clang/ICPC, ``/GL`` - and ``/LTCG`` on Visual Studio). Default-hidden symbols on GCC/Clang/ICPC - (``-fvisibility=hidden``) and .OBJ files with many sections on Visual Studio - (``/bigobj``). The :ref:`FAQ ` contains an + and ``/LTCG`` on Visual Studio) and .OBJ files with many sections on Visual + Studio (``/bigobj``). The :ref:`FAQ ` contains an explanation on why these are needed. Embedding the Python interpreter diff --git a/docs/faq.rst b/docs/faq.rst index 072b157292..8f33eb014a 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -151,6 +151,33 @@ specifying a larger value, e.g. ``-ftemplate-depth=1024`` on GCC/Clang. The culprit is generally the generation of function signatures at compile time using C++14 template metaprogramming. +.. _`faq:hidden_visibility`: + +"‘SomeClass’ declared with greater visibility than the type of its field ‘SomeClass::member’ [-Wattributes]" +============================================================================================================ + +This error typically indicates that you are compiling without the required +``-fvisibility`` flag. pybind11 code internally forces hidden visibility on +all internal code, but if non-hidden (and thus *exported*) code attempts to +include a pybind type (for example, ``py::object`` or ``py::list``) you can run +into this warning. + +To avoid it, make sure you are specifying ``-fvisibility=hidden`` when +compiling pybind code. + +As to why ``-fvisibility=hidden`` is necessary, because pybind modules could +have been compiled under different versions of pybind itself, it is also +important that the symbols defined in one module do not clash with the +potentially-incompatible symbols defined in another. While Python extension +modules are usually loaded with localized symbols (under POSIX systems +typically using ``dlopen`` with the ``RTLD_LOCAL`` flag), this Python default +can be changed, but even if it isn't it is not always enough to guarantee +complete independence of the symbols involved when not using +``-fvisibility=hidden``. + +Additionally, ``-fvisiblity=hidden`` can deliver considerably binary size +savings. (See the following section for more details). + .. _`faq:symhidden`: @@ -192,11 +219,14 @@ world. So we'll generally only want to export symbols for those functions which are actually called from the outside. This can be achieved by specifying the parameter ``-fvisibility=hidden`` to GCC -and Clang, which sets the default symbol visibility to *hidden*. It's best to -do this only for release builds, since the symbol names can be helpful in -debugging sessions. On Visual Studio, symbols are already hidden by default, so -nothing needs to be done there. Needless to say, this has a tremendous impact -on the final binary size of the resulting extension library. +and Clang, which sets the default symbol visibility to *hidden*, which has a +tremendous impact on the final binary size of the resulting extension library. +(On Visual Studio, symbols are already hidden by default, so nothing needs to +be done there.) + +In addition to decreasing binary size, ``-fvisibility=hidden`` also avoids +potential serious issues when loading multiple modules and is required for +proper pybind operation. See the previous FAQ entry for more details. Another aspect that can require a fair bit of code are function signature descriptions. pybind11 automatically generates human-readable function diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index 44a33458da..54760cdbc9 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -12,7 +12,7 @@ #include "cast.h" -NAMESPACE_BEGIN(pybind11) +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) /// \addtogroup annotations /// @{ @@ -478,4 +478,4 @@ constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) { } NAMESPACE_END(detail) -NAMESPACE_END(pybind11) +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/include/pybind11/buffer_info.h b/include/pybind11/buffer_info.h index 6d1167d212..1f5e3a9531 100644 --- a/include/pybind11/buffer_info.h +++ b/include/pybind11/buffer_info.h @@ -11,7 +11,7 @@ #include "common.h" -NAMESPACE_BEGIN(pybind11) +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) /// Information record describing a Python buffer object struct buffer_info { @@ -105,4 +105,4 @@ template struct compare_buffer_info #endif -NAMESPACE_BEGIN(pybind11) +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) NAMESPACE_BEGIN(detail) // Forward declarations: inline PyTypeObject *make_static_property_type(); @@ -2084,4 +2084,4 @@ NAMESPACE_END(detail) template<> class type_caster : public type_caster_base { }; \ }} -NAMESPACE_END(pybind11) +NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/include/pybind11/chrono.h b/include/pybind11/chrono.h index 8a41d08b0c..95ada76e0f 100644 --- a/include/pybind11/chrono.h +++ b/include/pybind11/chrono.h @@ -27,7 +27,7 @@ #define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta*)o)->microseconds) #endif -NAMESPACE_BEGIN(pybind11) +NAMESPACE_BEGIN(PYBIND11_NAMESPACE) NAMESPACE_BEGIN(detail) template class duration_caster { @@ -159,4 +159,4 @@ template class type_caster