You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
then check(make()); succeeds if make() and check() are compiled in the same module, but fails if make() and check() are put in separate modules.
I believe the problem comes from interaction between:
each module defines its own copy of Foo<int> typeinfo
clang dynamic_cast<> implementation compares typeinfo pointers, so relies on ODR being satisfied in executable for typeinfo objects.
for template classes, compiler may be forced to store typeinfo in multiple places, possibly in every .o file that depends on the class declaration.
default "two-level namespace linking" allows typeinfo instances from separate modules to resolve separately in an executable. In particular appears to defeat coalescing of weak external references.
In my project, managed to workaround by disabling two-level namespaces.
Needed to make two kinds of change to CMakeLists.txt files:
# set linker flags for non-pybind11 shared libraries
add_link_options("$<$<PLATFORM_ID:Darwin>:LINKER:-flat_namespace>")
# or
target_link_options(mytarget PRIVATE "$<$<PLATFORM_ID:Darwin>:LINKER:-flat_namespace>")
# also need to set linker flags for pybind11 shared libraries
set_property(
TARGET pybind11::python_link_helper
APPEND
PROPERTY INTERFACE_LINK_OPTIONS "$<$<PLATFORM_ID:Darwin>:LINKER:-flat_namespace>"
)
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Ran into the following issue using following toolchain:
Have a project involving multiple shared libraries, and multiple pybind11 modules. All symbols are using default visibility.
If we have the following:
module A:
module B:
then
check(make());
succeeds ifmake()
andcheck()
are compiled in the same module, but fails ifmake()
andcheck()
are put in separate modules.I believe the problem comes from interaction between:
Foo<int>
typeinfodynamic_cast<>
implementation compares typeinfo pointers, so relies on ODR being satisfied in executable for typeinfo objects.In my project, managed to workaround by disabling two-level namespaces.
Needed to make two kinds of change to CMakeLists.txt files:
references:
https://www.russellmcc.com/posts/2013-08-03-rtti.html#foot1
https://stackoverflow.com/questions/47322895/dynamic-cast-doesnt-work-across-module-boundaries-on-clang
Beta Was this translation helpful? Give feedback.
All reactions