How can I statically link libc++ under linux?

So I’m building a plugin, which links libc++ and is compiled with clang.

when I load that plugin, it always complains undefined symbol “_ZNKSt3__119__shared_weak_count13__get_deleterERKSt9type_info”

I’m attempting to resolve it by statically link to libc++.

if I google online, most answers say adding -static, but it doesn’t work at all. I found this discussion, ⚙ D96070 [clang] [driver] Enable static linking to libc++ , which got me confused. is this function working at all?

I’m currently trying everything I can think of"

                "-fuse-ld=ld.lld",
                "-pthread",
                "-nostdlib++",
                "-Wl,--push-state,-Bstatic",
                "-v",
                "-lc++",
                "-lm",
                "-lc",
                "-Wl,--pop-state",
                "-lc++abi",
                "-static",
                "-stdlib=libc++",
                "-Wl,-undefined,error"

they don’t work at all, after building, if I check symbols using nm, I can still see the symbol is missing.

what’s the right way to do it?

right now, the only way to get the plugin loaded is doing

LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libc++.so.1.0

and even with the above build flags, if I check the so file with objdump -x:

Dynamic Section:
  NEEDED               libm.so.6
  NEEDED               libstdc++.so.6
  NEEDED               libopenjp2.so.7
  NEEDED               libgcc_s.so.1
  NEEDED               libc.so.6

it still loads libstdc++

2 Likes

I had the same issue with my library linked statically against libc++ with LLVM 13. The lld-13 linker is required to fix this in my case. You already link using lld but you lack the part how to do static linking. It is done by the linker options -nostdlib++ /usr/lib/llvm-13/lib/libc++.a /usr/lib/llvm-13/lib/libc++abi.a. See: ⚙ D96070 [clang] [driver] Enable static linking to libc++

I use the linker flags -pthread -static-libgcc -ldl -fuse-ld=lld-13 -Wl,--version-script=${PWD}/export.map -nostdlib++ /usr/lib/llvm-13/lib/libc++.a /usr/lib/llvm-13/lib/libc++abi.a now.
The export.map is required for not exporting libc++ symbols and causing segfaults this way. Export only the public API of your library or nothing otherwise by using

{
  global:
    MyEntyPointFunction;
  local: *;
};

-lc++ and -lc++abi create dynamic linking. -stdlib=libc++ is only for compile phase. -static is only for statically linked executable (avoid this, as statically linking libc is a bad thing).

I hope this helps you and others who find this via web search like I did.

1 Like