- Add a new WITH_LIBCXXABI (defaults to off) to use libcxxabi instead of libcxxrt.
- Add unmodified sources for src/ and include/ from libcxxabi.
- Add a FreeBSD-upgrade file.
- Add a first cut at a libcxxabi Makefile and a Version.map that is just a copy of libcxxrt for now.
- Sprinkle MK_LIBCXXABI in various places. In some cases the libcxxabi bits don't exist yet.
- just working on building for now, will eventually install into a chroot and test C++ programs that throw exceptions in the chroot
For the rest this all looks OK to me, I'll see if I can find some time to try it out in a sandbox.
Btw for now I'd use the version from the release_80 branch, which is still under the original UIUC/MIT license. At some point the whole of the llvm import will be ASL2-with-exception, but for now maybe hold it off?
Oh, I just copied the bits out of the monorepo from git for the WIP. libcxxabi isn't in ^/vendor yet. I'm hoping that we won't need many (if any) local diffs to libcxxabi itself, so once I have the PoC working I was hoping you could import libcxxabi into the vendor area and do a proper copy into contrib and then I'd rebase my tree on top of that. I just didn't want to do the repo churn in ^/vendor if it turns out to not work for some reason.
So this might not be what we want to do. Ugh. Because we use a linker script here for libc++, existing binaries have DT_NEEDED entries explicitly for libcxxrt.so.1. I guess we had a good reason for doing that rather than having libc++.so.1 have a DT_NEEDED. Anyway, this means that the current approach here will require us to keep providing a libcxxrt.so.1 as a compat library (maybe in compatX packages) and that new binaries will explicitly depend on libcxxabi.so.1. We could perhaps instead install libcxxabi.so.1 as libcxxrt.so.1 instead. Not sure which is better / worse. Perhaps I will end up adjusting this patch so that we build and install both libraries for now and the knob just affects what libc++ builds against and what the ldscript is. Blech.
The reason for the script was to make it possible for users to edit it, so they could switch between libsupc++ and libcxxrt, as far as I remember. Maybe it's best for the future to have libc++.so.1 requiring libc++abi.so now, or add some sort of compat symlink.
A snapshot that builds.
- Install as libc++abi.so since that is what libc++'s cmake normally expects.
- Fix various other Makefiles that directly use libcxxrt.
- Use '=' prefixes in the libc++ ldscript so that it works with --sysroot.
This is now working on amd64 without requiring any changes to libcxxabi. I discussed some other thoughts on unwind.h with Ed on IRC that I might do in a separate change first, but I think we could try some more testing and/or go ahead and import libcxxabi into vendor and contrib and then I'll update this tree to be relative to that.
Speaking of #includes, on OS X, cxxabi.h and __cxxabi_config.h are installed in /usr/include rather than /usr/include/c++/v1, meaning that /usr/include/c++/v1 is just libc++ includes. I think I probably prefer that approach which would include moving unwind.h and friends to /usr/include as well.
One thing I don't understand currently is that right now we statically compile part of libcxxrt into libc++, but then we still link libc++ against libcxxrt. FWIW, OpenBSD statically compiles libunwind into their libc++abi, but I think they only use libc++ and lib++abi on aarch64 currently.
I don't see the use of putting cxxabi.h in /usr/include, it's a C++ only header. Or at least, all the real functionality is between #ifdef __cplusplus guards. That makes it rather useless as a general C header? For unwind.h the situation is different, the functions in there are just fine to use from a C program.
One thing I don't understand currently is that right now we statically compile part of libcxxrt into libc++, but then we still link libc++ against libcxxrt.
This is only done for libc++.a. In lib/libc++/Makefile it adds all the CXXRT_SRCS to STATICOBJS, it does *not* add them to libc++.so.1. The latter can use either libsupc++, libcxxrt or libcxxabi via the libc++.so linker script.
FWIW, OpenBSD statically compiles libunwind into their libc++abi, but I think they only use libc++ and lib++abi on aarch64 currently.
That makes libunwind unusable by any other program? I don't see the use of that.
Ok, I will switch to installing libcxxabi's cxxabi.h header for libcxxabi. One question is if it would be simpler/cleaner to install the cxxabi.h header and it's friends in the respective Makefile (libcxxrt/Makefile and libc++abi/Makefile) rather than doing it in libc++/Makefile. I feel like that is cleaner.
For the static libc++.a case, I wish there was a way to force libc++.a to just suck in all the static objects from some other .a rather than building them a second time. :-/
Please do not do this. libc++abi implements the Itanium ABI specification, but *not* GNU extensions. This is fine for Apple, because their Objective-C exceptions are thin wrappers around C++ exceptions, but other languages on non-Apple platforms (Objective-C definitely, I think Ada and a few others) rely on GNU extensions. These are supported by libsupc++ and libcxxrt. There's a reason that the product groups at $WORK picked libcxxrt for things that ship libc++...
If there are any features missing from libcxxrt, please open issues and assign them to me.
An issue I'm aware of is deficiencies in the C++ demangler, inherited from ELF Tool Chain.
Issues in ELF Tool Chain's issue tracker:
I'd be very happy to replace the libelftc demangler with the one from libc++abi, but last time this was discussed there were some complaints about the significant increase in binary size. One solution that I'd considered is to replace the demangler in libc++abi with a stub that doesn't actually do any demangling and then import the libc++abi demangler into libc++, possibly excluding it from release builds of the static library (dynamically linked programs probably don't mind paying the size overhead).
Having suffered from OpenBSD's decision to import libc++abi and having had to drop OpenBSD support for Objective-C as a result, I'd really like to avoid FreeBSD going this route.
Fair point, and I agree - if our only concern is the demangler then switching the whole lib over to get a different demangler seems excessive.
We should probably try to coordinate with other libcxxrt users to make sure we have a common view of libcxxrt's future.
I had labored under the incorrect assumption that libcxxrt was somewhat abandoned and that all other libc++ consumers used libc++abi, however, it seems that it's only Apple and OpenBSD that use libc++abi. NetBSD still uses libcxxrt. Also, when I compared the repositories both libcxxrt and libcxxabi had basically no real activity in the last two years. libcxxabi had more commits, but they were all due to relicensing and moving to monorepo.
There haven't been any commits to libcxxrt because it is a complete implementation of the GNU extensions to the Itanium and ARM C++ runtime library ABIs. I suspect that C++20 will introduce some features that require extensions to the ABI and so there may be a bit of activity this year, but aside from that it's in maintenance mode. If there are any open issues, please make sure that they are filed upstream and assigned to me.