Better support for statically linking libc++/libc++abi


Chrome for Android switched to libc++ in version 45, which launched a few weeks ago. This went well, thanks for everyone working on libc++ for the great work :slight_smile: (If anyone is curious about the issues we had during the transition I’m happy to expand on that, but most of it was fairly boring – tests relying on the iteration order of hash_set etc.)

One feature request of sorts: Chrome for Android statically links libc++ (except for ASan builds, we link dynamically in that case). One side effect of the switch is that the chrome binary grew quite a few public symbols from the libc++ headers. Chrome is built with -fvisibility=hidden, but a bunch of places in libc++ contain explicit visiblity(“default”) annotations. These make a lot of sense for shared-library builds of libc++, but for static library builds it makes less sense.

It looks like it might be possible to work around this by defining _LIBCPP_FUNC_VIS, _LIBCPP_TYPE_VIS, _LIBCPP_EXCEPTION_ABI to nothing, but that seems a bit hacky. (I also don’t know if the prebuilt libc++.a in the Android NDK was built like that, but that’s probably off-topic for this list :slight_smile: Also, those symbols can be suppressed via -Wl,–exclude-libs=libc++_static.a anyhow).

In the same vein: Symbols in libc++abi have the same issue, but there’s not even a workaround for it there as far as I can tell – there are a bunch of literal __visibility__("default") and #pragma GCC visibility push(default)s scattered around. (We don’t currently use libc++abi in chrome/android – we use libgcc and libatomic for now, and we still build with gcc.)

My requests:

  1. Would it be possible to put the visibility annotations in libcxxabi behind some macro, so that projects can choose to get private visibility for everything?
  2. Is defining the three macros I mentioned above a good way to force symbols to not have public visibility in libc++, or should projects not rely on that? In the latter case, could there be an explicit, supported toggle for this too?


I forgot a third one:
3. It'd be cool if there was some supported way to build libc++abi in a way
that makes it not add a dependency on cxa_demangle() from
default_terminate_handler() in cxa_default_handlers.cpp. This one call
keeps cxa_demangle() alive, and that takes several hundreds kB of code. For
apps sensitive to size (e.g. mobile apps), paying this size cost for almost
no benefit seems suboptimal. (We're currently adding an empty
cxa_demangle() to one of our source files so that the linker picks that
over the one in libc++abi, but that's fairly hacky.)

I'm happy to do the typing for each of these three if there's agreement
that either of these would be a useful thing to have.


FWIW I’ve received requests to do something about the demangler in the NDK as well, so +1 to having a less hacky work around.

The demangler is supposed to be part of the ABI library independently.
It should be rewritten, compare the code for the demangle implementation
in libc++rt. Howard became a victim of requests for early
overgeneralisation :frowning:


This is why libcxxrt includes a simpler demangler. We considered importing the one from libc++abi, but decided that the increase in code size was not worth it.

For what it’s worth, I’ve heard from a couple of companies shipping the combination of libcxxrt and libc++ in their Android apps for precisely this reason.


Eric, Marshall: Ping about the symbols visibility questions :slight_smile:

If you’re around for the conference Thursday / Friday, we could talk there too.

It looks like compnerd is going the more useful "send patch, not email"
route for (1) here:

I'd still appreciate if defining projects defining these macros to nothing
is considered a good idea, or if these are considered "internal" macros.

Eric told me he's fine with something for (3) over IRC, so that part
probably only needs a patch too.