LibreOffice bug report “Build failure with clang++/libc++ on Linux x86_64” and reports about a similar failure when trying to build on NetBSD made me look at building LibreOffice on Linux with Clang against libc++/libc++abi (instead of the usual libstdc++) myself.

The libc++ web site warns: “Unfortunately you can’t simply run clang with ‘-stdlib=libc++’ at this point [when you have built Clang to be able to use libc++ in combination with libc++abi], as clang is set up to link for libc++ linked to libsupc++.” But that appears to no longer be true (at least on current LLVM trunk). All it takes is to include the libcxx and libcxxabi repositories in the projects sub-directory of the LLVM/Clang source tree and build it. The resulting libc++.so includes the necessary -lc++abi , so building LibreOffice with CXX=clang++ -stdlib=libc++ just works. (You need to make sure that the libc++.so.1 gets found at runtime, of course, e.g., by setting LD_LIBRARY_PATH .)

One remaining problem is that libc++abi and libstdc++ (resp. its ABI-related libsupc++ part) differ in how they determine type equivalence. On the one hand, libc++abi sticks to the original C++ ABI semantics: “It is intended that two type_info pointers point to equivalent type descriptions if and only if the pointers are equal.” (That is, type equivalence is determined by comparing _ZTI * type_info pointers for equality.) On the other hand, libstdc++ relaxed this quite a while ago to comparing type_info s’ name fields ( _ZTS * ) for string equality (via strcmp ).

While both approaches have pros and cons, they do lead to different behaviour. One example is when a dynamic library is dlopen ’ed RTLD_LOCAL . If code in that library (or any library that gets loaded dependent of it) throws an exception of type T , and code beyond that RTLD_LOCAL “wall” shall catch it, then that will work with the libstdc++ approach but fail with the libc++abi approach (even if all the relevant _ZTI * , _ZTS * symbols are weakly exported).

That is the reason why e.g. the UNO runtime makes sure to dlopen all relevant libraries as RTLD_GLOBAL , but LibreOfficeKit/LibreOfficeKitInit.h somewhat ignorantly tries to get away with dlopen ’ing the sofficeapp library as RTLD_LOCAL . Now LibreOffice’s cppunittester executable (used to run CppUnit tests during the LibreOffice build) links against the sal library. So by the time CppunitTest_libreofficekit_tiledrendering dlopen ’s the sofficeapp library as RTLD_LOCAL , the sal library has already been loaded into the process (implicitly as RTLD_GLOBAL ), so any UNO components that happen to get instantiated in that process (via the dlopen in sal ’s osl_loadModule ) will be outside that “ sofficeapp RTLD_LOCAL walled garden,” so that when code in ucb/source/ucp/file/bc.cxx throws a css::ucb::CommandFailedException , code in ucbhelper/source/client/content.cxx (inside the walled garden) won’t catch it (but would instead proceed to std::unexpected , std::terminate , std::abort ).

That problematic dlopen with RTLD_LOCAL had already been addressed for UBSan builds (where runtime type identification code in at least Clang’s UBSan implementation always operates under the original C++ ABI semantics, regardless of compiler ABI library used), “Ensure RTTI symbol visibility for Linux Clang -fsanitize=function,vptr.” The only problem this time is to find a suitable #if condition to distinguish usage of libc++abi from usage of other compiler ABI libraries, “[cfe-dev] Feature-test macro whether compiling against libc++abi?”