Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Visibility hidden #995

Merged
merged 6 commits into from
Aug 14, 2017
Merged

Visibility hidden #995

merged 6 commits into from
Aug 14, 2017

Conversation

jagerman
Copy link
Member

This is a few commits to force hidden visibility on the pybind11 namespace and to unconditionally add it into the compilation flags (also this sets the flag through the cmake property rather than setting the actual compilation flags).

This needs one more thing before merging--the FAQ entry talking about hidden visibility seems largely obsolete with these changes. Should we shorten it? Amend it? Drop it?

@jagerman jagerman mentioned this pull request Aug 10, 2017
Copy link
Member

@dean0x7d dean0x7d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs one more thing before merging--the FAQ entry talking about hidden visibility seems largely obsolete with these changes. Should we shorten it? Amend it? Drop it?

The one about small binaries? I'd leave it as is. It's very informative. What would be nice is a new FAQ entry about the possible visibility warning and how to resolve it.

@@ -12,7 +12,7 @@

#include "cast.h"

NAMESPACE_BEGIN(pybind11)
NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be simpler to add the visibility attribute to the NAMESPACE_BEGIN macro instead of introducing a new one?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm against that, for selfish reasons :). I have several other projects that use the NAMESPACE_BEGIN macro, where that behavior may not be intended.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I guess that's why NAMESPACE_BEGIN/END are the only macros not prefixed with PYBIND11 :)

# py::module_local). We force it on everything inside the `pybind11`
# namespace; also turning it on for a pybind module compilation here avoids
# potential warnings or issues from having mixed hidden/non-hidden types.
set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET "hidden")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

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
strongly recommended for pybind11 modules, can interfere with the ability to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's required, not just recommended anymore. Maybe simplify to something along the lines of: "By default, pybind11 modules are compiled with hidden symbol visibility (see :ref:...), which can interfere..."

via the command line flag ``-fvisibility=hidden`` on GCC/Clang), which is
strongly recommended for pybind11 modules, can interfere with the ability to
access types defined in another extension module. Working around this requires
manually export types that are accessed by multiple extension modules; pybind11
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exporting

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weird question, but: Why two spaces after a period?

Copy link
Member Author

@jagerman jagerman Aug 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In monospace fonts, it is visually closer to, e.g., a TeX inter-sentence space. It's also consistent with what you get from tools like man when used in a terminal. And while I do think it looks a bit better, it's mainly habit: I do it without even thinking about it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also (I just noticed) vim does this automatically when rewrapping (e.g. if a line ends with a .). I'd be quite surprised if there isn't an option to control that, but it isn't something I turned on specifically.

(``-fvisibility=hidden``) and .OBJ files with many sections on Visual Studio
(``/bigobj``). The :ref:`FAQ <faq:symhidden>` contains an
and ``/LTCG`` on Visual Studio) and .OBJ files with many sections on Visual
Studio (``/bigobj``). The :ref:`FAQ <faq:symhidden>` contains an
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike pybind11_add_module(), the CMake targets haven't been including any visibility flags. It would be good to point this out here.

Alternatively, the visibility property could be added to the targets, but that's somewhat of a breaking change.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, actually I meant to add that as well but forgot. Why would it be breaking?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the library was relying on the default visibility to export symbols, the change would break cross-module types. It would require a one line change in CMake to restore default visibility, so it might not be a big deal.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems it's not so easy to add it; there isn't any sort of INTERFACE_CXX_VISIBILITY_PRESET, which means we'd be back to figuring out when to add it based on compilers ourselves. Better, I think, to just document that target users should set the property themselves.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition should be as simple as if(NOT MSVC), shouldn't it?

After some thinking, I feel that the hidden visibility should be enforced as much as possible. With an increasing number of pybind11 modules on PyPI, it would be quite easy to run into internals versioning issues and/or bindings of common STL containers.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'll add it in.

This adds a PYBIND11_NAMESPACE macro that expands to the `pybind11`
namespace with hidden visibility under gcc-type compilers, and otherwise
to the plain `pybind11`.  This then forces hidden visibility on
everything in pybind, solving the visibility issues discussed at end
end of pybind#949.
…iler flag

This should resolve the issues with default visibility causing problems
under debug compilations.  Moreover using the cmake property makes it
easier for a caller to override if absolutely needed for some reason.
@dean0x7d dean0x7d added this to the v2.2 milestone Aug 13, 2017
CMakeLists.txt Outdated
@@ -91,6 +91,9 @@ if(NOT (CMAKE_VERSION VERSION_LESS 3.0)) # CMake >= 3.0
$<BUILD_INTERFACE:${PYTHON_INCLUDE_DIRS}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
target_compile_options(pybind11 INTERFACE $<BUILD_INTERFACE:${PYBIND11_CPP_STANDARD}>)
if(NOT MSVC)
target_compile_options(pybind11 INTERFACE $<BUILD_INTERFACE:-fvisibility=hidden>)
Copy link
Member

@dean0x7d dean0x7d Aug 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for build/install interface separation here because the same flag is applied to both. If target_compile_options(pybind11 INTERFACE -fvisibility=hidden) is set here, then nothing needs to be added to pybind11Config.cmake.

@dean0x7d
Copy link
Member

LGTM!

@jagerman jagerman merged commit cd58be7 into pybind:master Aug 14, 2017
@jagerman jagerman deleted the visibility-hidden branch August 14, 2017 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants