What (if any) is a good way of handling the ABI inconsistency between libc++ and stdlibc++ on Mac?
The problem: Many c++11 features require the new libc++ implementation of the C++ standard library. But libc++ is not ABI-compatible with the old libstdc++, while currently most software typically links against the latter. For example the system compiler still uses stdlibc++ which means that all my libraries installed with macports have a different ABI for std-classes like string and are unlinkable with projects that make heavy use of c++11.
My current hack-of-a-solution: Keep two versions of libraries where this commonly leads to an issue (boost, opencv etc.) and link to the appropriate one.
I guess that one might suggest that if I really want to make use of libc++ I should purge my system of anything using stdlibc++, and make sure that anything from macports (or anywhere else) only links with libc++. You could see how daunting this task seems.
Has anyone worked out a nice way of relating to this "between-stdlib-limbo" that we are living in? :)
EDIT: I'm making an implied follow-up question more explicit: Apple ships both libc++ and libstdc++ with their systems. Assuming one attacks the underlying problem and tries to make a switch to libc++-only. What would be the recommended way of switching from libstdc++ to libc++ given that 100% of the libraries currently installed on your system (some shipped with the system, most of them via macports, a few via manual compilation) are linked to libstdc++ (if any)? Has anyone done this and survived?
A complete ABI, such as the Intel Binary Compatibility Standard (iBCS), allows a program from one operating system supporting that ABI to run without modifications on any other such system, provided that necessary shared libraries are present, and similar prerequisites are fulfilled.
libc++abi is a new implementation of low level support for a standard C++ library. All of the code in libc++abi is dual licensed under the MIT license and the UIUC License (a BSD-like license).
These details are defined as the compiler Application Binary Interface, or ABI. From GCC version 3 onwards the GNU C++ compiler uses an industry-standard C++ ABI, the Itanium C++ ABI. The GNU C++ compiler, g++, has a compiler command line option to switch between various different C++ ABIs.
Most implementations of libstdc++ depend on libc, so they require it. The C++ standard includes most of the C standard library. So it's kind of a dependency and technically it's part of the C++ standard library.
Barring 'hidden' uses of standard library types it is perfectly safe to mix libc++ and libstdc++ in a single program, where some TUs (or libraries, or modules) use libc++ and some use libstdc++. As long as the interfaces between TUs do not use the incompatible types there shouldn't be any problems.
libc++ uses inline namespaces to help ensure that ABI incompatible types cannot be mistaken for one another; if an interface uses libc++ std::string
directly a library expecting libstdc++ std::string
will not link to the interface, because the actual symbols are different: std::string
vs. std::__1::string
.
libc++ also ensures that low level features like exceptions and dynamic memory allocation are ABI compatible (assuming you build libstdc++ and libc++ using the same abi library), so it's safe to deallocate memory in a TU that uses, say, libc++ when the memory was allocated in a TU using libstdc++, or to throw an exception from code build on libc++ and catch it in code using libstdc++.
There can be a problem when types in interfaces hide standard library types; given an interface using struct S { std::string s; };
the definition of the type S
will be different depending on what the TU thinks std::string
is, thus violating the one definition rule.
However it sounds as if your real problem is with libraries that do use standard library types in interfaces.
I guess that one might suggest that if I really want to make use of libc++ I should purge my system of anything using stdlibc++, and make sure that anything from macports (or anywhere else) only links with libc++. You could see how daunting this task seems.
You only need to ensure that TUs that use the standard library in interfaces use libc++. You do not need to completely purge libstdc++. Libraries that don't use the standard library in their interface can still go on linking with libstdc++.
EDIT: I'm making an implied follow-up question more explicit: Apple ships both libc++ and libstdc++ with their systems. Assuming one attacks the underlying problem and tries to make a switch to libc++-only. What would be the recommended way of switching from libstdc++ to libc++ given that 100% of the libraries currently installed on your system (some shipped with the system, most of them via macports, a few via manual compilation) are linked to libstdc++ (if any)? Has anyone done this and survived?
Remember, it only matters when the standard library is being used in interfaces. Hopefully such libraries are already switching to libc++ on their own when they build for OS X. If not, perhaps they'll accept patches to do so.
Building your own binaries using the appropriate library is not a 'hack'; it is the correct thing to do absent the upstream project doing it for you. If you consistently use libc++ in your own code then you will not need to build multiple versions of any library; only libc++ versions.
reference for abi compatibility of libc++: http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-September/024594.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With