I'm using clang 10 and gcc 9 on Ubuntu 20.04.
Taking this following sample program:
#include <cstdio>
#include <any>
int main(int argc, char* argv[])
{
std::any v = argc;
printf("value: %d\n", std::any_cast<int>(v));
}
I can compile it with clang like this:
clang++ test.cpp -std=c++20 -static-libstdc++ -static-libgcc
and end up with this binary:
$ ldd a.out
linux-vdso.so.1 (0x00007fffd92f9000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f169be49000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f169bc57000)
/lib64/ld-linux-x86-64.so.2 (0x00007f169bf9e000)
Now I'd like to use LLVM's libc++
in my program and link it statically, just as I'm linking libstdc++ statically above. But there's no -static-libc++
equivalent; I can do this:
clang++ test.cpp -std=c++20 -stdlib=libc++ -static-libstdc++ -static-libgcc
but then I receive many link errors due to the fact that libc++abi
is not linked. Running the above command with -v
further confirms the suspicion:
"/usr/bin/ld" [...] /tmp/test2-f20a4a.o -Bstatic -lc++ -Bdynamic -lm -lgcc -lgcc_eh
# ^^^^^^^^^^^ no -lc++abi!
-lc -lgcc -lgcc_eh /usr/bin/../lib/gcc/x86_64-linux-gnu/9/crtend.o /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crtn.o
There is a -static
option available, but that's not the same: it links everything statically, including libc, which is generally recommended against (and, on my system, it still doesn't link libc++abi and produces multiple link errors).
The best way I've been able to find is to link in a separate step, pass -nostdlib++
and manually pass linker flags to statically link libc++
and libc++abi
:
clang++ test.cpp -std=c++20 -stdlib=libc++ -c
clang++ test.o -nostdlib++ -static-libgcc -Wl,--push-state -Wl,-Bstatic -lc++ -lc++abi -Wl,--pop-state -lpthread
ldd a.out
linux-vdso.so.1 (0x00007fff20dfe000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9ef6a97000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9ef6948000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9ef6756000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9ef6ac0000)
This does work, but it seems strange that clang wouldn't support doing this more readily, without manually messing with the linker. Is there no other way?
-static-libstdc++
works forlibc++
as well for newer versions of Clang. It worked for me with Clang 14, but not with Clang 10. – Philhellene