Fix macOS Python 3.14 std::bad_any_cast by setting hidden visibility preset - #2041
Conversation
…std::any_cast pybind11 type_info mismatches across boundaries Signed-off-by: Michael Oliver <mcoliver@gmail.com>
|
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2041 +/- ##
==========================================
+ Coverage 83.25% 83.47% +0.21%
==========================================
Files 180 182 +2
Lines 13479 13517 +38
Branches 1253 1254 +1
==========================================
+ Hits 11222 11283 +61
+ Misses 2085 2061 -24
- Partials 172 173 +1
Flags with carried forward coverage won't be shown. Click here to find out more. Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
SerializableObject's destructor, its Reader's any overload and type check, and its Writer's int64_t overload had no OTIO_API on them. A build that hides its symbols by default, which main does since AcademySoftwareFoundation#2041, leaves them out of the library and upgrade_downgrade_example cannot be linked. Signed-off-by: Darby Johnston <darbyjohnston@yahoo.com>
|
@jminor This change breaks shared builds due to some missing exports. The symbols with missing exports get hidden by this which then cause linker errors. We should merge #2039 to fix the missing exports which might also make this change unnecessary. I also need to add a CI job that builds shared libraries to catch things like this. |
SerializableObject's destructor, its Reader's any overload and type check, and its Writer's int64_t overload had no OTIO_API on them. A build that hides its symbols by default, which main does since AcademySoftwareFoundation#2041, leaves them out of the library and upgrade_downgrade_example cannot be linked. Signed-off-by: Darby Johnston <darbyjohnston@yahoo.com>
* Export the API correctly for shared builds on Windows OTIO_EXPORTS and OPENTIME_EXPORTS were PUBLIC, so everything consuming OTIO compiled its API as dllexport where it has to be dllimport. They become PRIVATE, which says the library is being built rather than consumed; the OTIO_STATIC and OPENTIME_STATIC definitions stay PUBLIC, since a consumer does have to know the API carries no declspec at all. With that corrected the members marked only at the class level came up missing, 74 of them, the Color statics and TypeRegistry among them: OTIO_API_TYPE is empty on Windows, where only the per-member OTIO_API carries the declspec. Those members are marked. The three find_children templates lose OTIO_API in turn, a template defined in a header being something that cannot be imported, and two source files that define exported functions without including the header that marks them are given the include. No change to what either library exports on macOS or Linux: the symbol tables of a shared build are identical before and after. Signed-off-by: Darby Johnston <darbyjohnston@yahoo.com> * Export the rest of what the examples link against SerializableObject's destructor, its Reader's any overload and type check, and its Writer's int64_t overload had no OTIO_API on them. A build that hides its symbols by default, which main does since #2041, leaves them out of the library and upgrade_downgrade_example cannot be linked. Signed-off-by: Darby Johnston <darbyjohnston@yahoo.com> --------- Signed-off-by: Darby Johnston <darbyjohnston@yahoo.com>
|
@darbyjohnston is correct. Apologies for not thinking deeper on the core issue. I was trusting the CI too much. I do think keeping the hidden visibility preset is good to have as a hardening measure in the event things are missed down the road but hopefully shared build CI should flag that. |
Fixes #2035.
When building the Python bindings (where the core libraries are linked statically into
_otio.so), pybind11 aggressively forces-fvisibility=hidden. Because the core library targets lacked visibility configuration, they were compiled with-fvisibility=default.On macOS, this mismatch generates duplicate
type_infostructures for template types likeRetainer<>. Since macOSlibc++evaluatestype_info::operator==via strict pointer equality, the dispatch table lookup insideotio_utils.cppthrows astd::bad_any_castwhen crossing the boundary frompybind11to the core library.Note the reason this probably doesn't show up on Linux is because Linux's libstdc++ compares by name as a fallback
By setting
CMAKE_CXX_VISIBILITY_PRESET hiddenandCMAKE_VISIBILITY_INLINES_HIDDEN ONglobally, the core library compiles with the exact same visibility rules aspybind11. The static linker then correctly collapses alltype_infoweak symbols into a single memory address, resolving the runtime exception on Python 3.14 macOS.