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

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

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

Don Hinton via cfe-dev
Hi,

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 :-) (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 :-) 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?

Thanks,
Nico

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

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

Don Hinton via cfe-dev
On Thu, Oct 15, 2015 at 2:20 PM, Nico Weber <[hidden email]> wrote:
Hi,

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 :-) (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 :-) 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.

Nico

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

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

Don Hinton via cfe-dev
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.

On Thu, Oct 15, 2015 at 9:16 PM, Nico Weber <[hidden email]> wrote:
On Thu, Oct 15, 2015 at 2:20 PM, Nico Weber <[hidden email]> wrote:
Hi,

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 :-) (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 :-) 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.

Nico


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

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

Don Hinton via cfe-dev
In reply to this post by Don Hinton via cfe-dev
On Thu, Oct 15, 2015 at 09:16:22PM -0700, Nico Weber via cfe-dev wrote:
> 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.)

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 :(

Joerg
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

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

Don Hinton via cfe-dev
In reply to this post by Don Hinton via cfe-dev
On 16 Oct 2015, at 05:16, Nico Weber via cfe-dev <[hidden email]> wrote:
>
> 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.)

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.

David

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

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

Don Hinton via cfe-dev
In reply to this post by Don Hinton via cfe-dev
Eric, Marshall: Ping about the symbols visibility questions :-)

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

On Thu, Oct 15, 2015 at 9:16 PM, Nico Weber <[hidden email]> wrote:
On Thu, Oct 15, 2015 at 2:20 PM, Nico Weber <[hidden email]> wrote:
Hi,

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 :-) (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 :-) 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.

Nico


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

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

Don Hinton via cfe-dev
In reply to this post by Don Hinton via cfe-dev
On Thu, Oct 15, 2015 at 9:16 PM, Nico Weber <[hidden email]> wrote:
On Thu, Oct 15, 2015 at 2:20 PM, Nico Weber <[hidden email]> wrote:
Hi,

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 :-) (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 :-) 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.

It looks like compnerd is going the more useful "send patch, not email" route for (1) here: http://reviews.llvm.org/D14789

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.

Nico

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev