[libcxx-dev] Handling of dependencies when statically linking C++ standard library

Petr Hosek via libcxx-dev libcxx-dev at lists.llvm.org
Mon Nov 19 14:16:48 PST 2018

Clang driver already includes -lm when linking C++ standard library.
However, when statically linking C++ standard library, that alone is
not sufficient. libstdc++ also depends on -lpthread, and libc++
depends on -ldl and -lpthread. This means that while user doesn't need
to specify -lm, they still need manually specify the missing link
dependencies with -static-libstdc++ which is cumbersome.

In the case of libc++, there's also the dependency on libc++abi and
libunwind when those are being used as ABI and unwinder. This means
that today when using libc++ with libc++abi and libunwind (and not
linking those into a single archive), `clang++ -stdlib=libc++
-static-libstdc++` is going to fail, the correct invocation is in fact
`clang++ -stdlib=libc++ -static-libstdc++ -lc++abi -lunwind -ldl
-lpthread` which is not a very user-friendly experience. I'd like to
improve this situation.

There are two possible solutions I came up with:

1. Extend the driver to automatically include the necessary
dependencies when statically linking C++ library. This doesn't require
any changes to either libc++ or libstdc++, but it makes the driver
more tied to the specifics of their implementation, but it's probably
no worse than other things that driver already does.

I have implemented this solution in D54724, reviews are welcome.

However, this doesn't handle libc++abi and libunwind because those
depend on libc++ build configuration which is vendor specific, e.g.
vendor might decide whether to use libc++ with libc++abi and
libunwind, whether to ship those separately or combine them all into a
single archive, and this is not something that driver is aware of.

2. Replace libc++.a with a linker script that contains something like
the following:

INPUT(libc++static.a libc++abi.a libunwind.a -ldl -lpthread)

This is similar to solution already used by shared libc++ and some
projects such as Chrome OS already use this same solution. There are a
few downsides: it requires linker with linker script support, and it
won't work for libstdc++ since this is typically provided by the host.
I also find the name libc++static.a aesthetically displeasing but I
couldn't come up with anything better. On the other hand it handles
the case of libc++abi and libunwind.

I have implemented this solution in D54726, again reviews are welcome.

Do you have any opinion on either on either of these solutions? Maybe
we need both?

More information about the libcxx-dev mailing list