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
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?