-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Make embind work with -fvisibility=hidden #22095
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
Conversation
This looks to be sufficient for Qt's use case. More types can be exported if needed. There's a bit more to it: ideally embind should work with non-exported ("hidden") types as well, and it looks like C++ API like std::type_info::hash_code() and std::type_index may not work correctly for non-exported types. Looking at at system/lib/libcxx/include/typeinfo, there are two options from implementing typeinfo:
Emscripten currently uses the default option 1, but does not generate unique RTTI for non-exported types in libraries/side modules. |
2969713
to
e053f23
Compare
@sbc100 Do you think there's some way we could properly have unique rtti for the program? |
76f29df
to
e7062a7
Compare
Note previous discussion on #16711 |
e7062a7
to
9391428
Compare
I think the way to achieve that is make sure the types are marked as This fix seems correct to me for the core embind types. They always want to be shared I think. We also have |
test/test_other.py
Outdated
self.set_setting('MAIN_MODULE', 1) | ||
|
||
@requires_dylink | ||
def test_embind_dylink_visibility_hidden(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks similar to what test_dylink_rtti
is doing in test_core.py
, but with some embind specifics. As such, perhaps it belongs alongside that test?
Rather than duplicating the three helper functions from test_core.py why not just put this test in test_core.py itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It also might make more sense alongside test_embind_no_rtti
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, tst_core could make sense as well (I had it there first). Is it primarily a dylink or embind test? test_embind_no_rtti sounds related, I'll check what that does.
(Note I have vacation time is coming up, so I'll get back to this in a couple of week's time.)
@msorvig would you mind updating this branch to re-run tests. |
With this patch I'm still getting |
@laminowany Do you have a small reproducer we could test with? |
@brendandahl unfortunately I don't really have a "small" case. Basically first I'm building the Qt framework from dev branch, then I'm building this https://github.com/mitchcurtis/slate using previously built Qt. |
The output from |
Here are flags I'm using: |
This line seems to cause an issue: |
Seems like |
I'm new to Emscripten project so I dont know a lot about codebase, feel free to correct me! So basically seems to me that types exported by embind: emscripten/system/lib/embind/bind.cpp Lines 122 to 136 in 1ddd294
have different typeIDs, if they come from different object files (i.e. side module vs main module). This is understandable given then typeID is generated using RTTI: emscripten/system/include/emscripten/wire.h Lines 64 to 69 in 1ddd294
(to be fair I'm not sure what is the lifetime of typeid object in Emscripten and if is safe to take its address) There is also other mechanism to generate typeIDs without RTTI which can be triggered by setting Could you point me @brendandahl into some direction?
|
Option 1 sounds interesting. I'm not that familiar with |
IIRC typeid in general should be stable across DLLs. I'm pretty sure we do have tests for it. The problem only occurs when you do |
After further investigation it seems like this patch is actually solving my problem! 😄 |
@msorvig are you still interested in getting this landed? I think it just requires a test update and it should be good to go. |
Hello, sorry for being a bit unresponsive - Yes, let's see if we can get this merged. I'm not 100% sure if this fixes completely the issue, but it should help. Emscripten should implement RTTI correctly also for unexported / -fvisibility=hidden types, and then embind can use type_info::hash_code() for its ID. type_info::name() was suggested above and is also an option, but it looks like the reference documentation at https://en.cppreference.com/w/cpp/types/type_info states that the name is not guaranteed to be unique or stable. |
789474b
to
560db4e
Compare
What is the status of it? Could we get it merged @sbc100 ? |
Export emscripten::val and emscripten::memory_view in order to prevent embind errors: BindingError: _emval_take_value has unknown type N10emscripten11memory_viewIhEE Embind generates a numerical type id from the address of the std::type_info object resulting from evaluating a typeid expressiion (e.g. 'void *id = &typeid(T)'). However, C++ does not guarantee that this address is identical for all evaluations of the typeid expression. In practice it is when using static linking, but not when using dynamic linking when the libraries are built with the '-fvisibility=hidden' compiler option. The non-identical id's then cause embind to decide that types have not been registered when used from a library, since they have been registered with a different id by the main wasm module. Exporting the types in question makes typeid addresses identical again, and fixes/works around the issue.
05efbbd
to
bd45403
Compare
@brendandahl is this good with you now? |
Thanks! ❤️ |
Export emscripten::val and emscripten::memory_view in order to prevent embind errors:
BindingError: _emval_take_value has unknown type N10emscripten11memory_viewIhEE
Embind generates a numerical type id from the address of the std::type_info object resulting from evaluating a typeid expressiion (e.g. 'void *id = &typeid(T)').
However, C++ does not guarantee that this address is identical for all evaluations of the typeid expression. In practice it is when using static linking, but not when using dynamic linking when the libraries are
built with the '-fvisibility=hidden' compiler option.
The non-identical id's then cause embind to decide that types have not been registered when used from a library, since they have been registered with a different id by the main wasm module.
Exporting the types in question makes typeid addresses identical again, and fixes/works around the issue.