-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
[BUG]: finer grained ABI compatibility #3793
Comments
I'm wondering if what you guys want to solve here is related to the issue I'm facing for quite some time already. I have two C++ libraries (autodiff and Reaktoro) for which The I have not been able to resolve this from my side; have tried already multiple solutions, additional conversion overloads, with no avail. I would appreciate to know if this is an unresolved issue in |
Is this different compilers or different C++ stdlib ABIs? |
The issue happens with both cases:
For example, this happened today when a new conda-forge package for Reaktoro was built with gcc 10.3, but the autodiff package available in conda-forge was built days ago with gcc 9.4. |
So I have a PR open to handle the conda-forge issues via the pybind11-abi package: conda-forge/pybind11-feedstock#79 The first item is out of my wheel house. |
I just want to state my support for make the ABI compatibly finer. I use classes from different modules and ship them using conda-forge. The current behaviour is just a nightmare on Linux: all involved modules have to be compiled with the same GCC major version. This means that when the compiler of conda-forge is updated:
|
The key question is: when is the ABI compatibility criterion in pybind11 too strict, and what can be done to make it more relaxed without running a risk of breaking things? (The same also applies to nanobind, which uses essentially the same kind of ABI tag) Let me add one correction: simply using different versions of GCC alone is not enough to cause issues -- pybind11 queries the ABI compatibility tag of libstdc++ ( At that point, it's basically your word against that of the These ABI tags haven't been introduced just for fun -- it's because things were crashing badly and in weird ways, and it was really complicated to track down what was going on. So any change here would need a very careful justification on why the coarser-grained flags are 100% guaranteed to avoid such issues, now and in the future. The alternative proposal @beckermr made at the top will cause less things from being isolated from each other, but it wasn't clear to me why it would provide such a guarantee. Note that this isn't just about pybind11 usage of Taking a step back, this seems to me to not be a pybind11 issue but a complaint about the One thing I have never tried, but which may be worth a shot, is to provide |
GXX_ABI_VERSION is too broad. Yes, there might have been an ABI break because of name mangling issues, but there is a compatibility scheme that adds a aliased symbol. See -fabi-compat-version in https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/C_002b_002b-Dialect-Options.html
It is when you have hundreds of downstream packages. Another issue with this system is that the current system breaks things silently whereas we haven't had an issue with the libstdc++ version for years. That's because of the |
Extensions which need to be part of the same "pybind11 domain" for C++ interop with custom types are sort of "buddies" with each other. Typical pybind11 extensions bind their own custom types but don't need such an intimate relationship with another extension. So that statement about hundreds of packages being affected seems high to me. I have a few follow-up questions:
|
It's automatically done by GCC. Nothing to do with conda-forge.
So, you have to consider that |
What I meant to ask here is: does CondaForge automatically specify Would it be a reasonable solution that the user -- when also specifying |
No. We use the compiler default.
Yes, that's what conda-forge/pybind11-feedstock#79 does. |
If I understood correctly, this commit completely disables ABI tagging (it unsets both PYBIND11_BUILD_ABI and PYBIND11_COMPILER_TYPE). That's a lot more severe than what I was suggesting. Besides potential incompatibilities related to My suggestion would be to find a more balanced version of this and make it part of either pybind11 proper or the CMake build system. PS: Let me just mention this comment about ABI compatibility from another project here since it nicely makes a point about pitfalls: (wjakob/nanobind#374 (comment))
|
I'm happy to not mix compiler types personally. |
Compilers like clang and gcc are usually okay to mix whereas the C++ standard library is not. Clang on Linux defaults to libstdc++ and it's okay as long as they both use I agree that we should check the C++ standard library, but the compiler itself is not a huge issue.
Isn't that precisely because of |
Hi @isuruf, @beckermr, and @rwgk, I had a bit of time look a bit into C++ ABI stability in the last few days. I think that I am too paranoid after having been repeatedly bitten by this some years ago. It seems that basically all the three main compiler tools (GCC, Clang, MSVC) have started taking ABI stability seriously at some point in the last years and there haven't been major breaks since then. So I'm open to making a change here that allows interoperability between more extensions built with different compilers. But let's get it right and make something that we hopefully won't have to tweak retroactively because the criterion turns out to be too loose and, e.g., and ancient GCC/Clang version turns out to not be ABI-compatible after all. I agree that mixing compilers should be okay, and that it's rather the C++ library ( One important think to keep in mind (@rwgk) is that a change here is itself an ABI break, of pybind11. Modifying the (I also plan to add whatever we converge upon to nanobind so that these two projects are consistent.) |
One more thing: this commit identifies a few discrete points where a But this is all very GCC specific. What about Clang? If we change the |
With respect to #4779 (merged already) & #4953 (pending): Before we merged #4779 we discussed the ABI break aspect, and accepted that as a necessary step to get to safety. We have not made a release yet after #4779 was merged, so we still have an opportunity to refine the change under #4953.
The major platforms (MSVC, g++, clang) are independent (AFAICT), I believe it might be more practical to focus on one platform at a time (unless we get more people involved). The released state for g++ and clang is pretty good, while it is very unsafe for MSVC. |
Required prerequisites
Problem description
Based on the extensive discussion in conda-forge plus offline discussion with @isuruf, we think there may be a better approach to ABI compatibility with respect to compilers and c++ runtimes.
Currently, pybind11 uses a combination of various things. The one of interest here is the
__GXX_ABI_VERSION
. This appears to be too strict, especially for forward-compatible libraries commonly in use.The suggestion is to replace
__GXX_ABI_VERSION
with__GLIBCXX_USE_CXX11_ABI
__GLIBCXX_USE_DEPRECATED
__SEH__
(only in clang I think)__SJLJ_EXCEPTIONS__
These capture the fine-grained, core ABI changes without being overly prescriptive. The last two are related to exception handling. There may be more macros to use to capture dwarf2 exceptions explicitly.
Thoughts @henryiii @isuruf?
Reproducible example code
No response
The text was updated successfully, but these errors were encountered: