Link problems with libc++abi when linking against

2019-07-02 01:48发布

问题:

I'm trying to build a simple ("hello world") C++ program with LLVM/Clang 3.7.0 built from sources against the toolchain's libc++, with the command line:

clang++ -std=c++14 -stdlib=libc++ -fno-exceptions hello.cpp

However, I get the following errors:

/usr/bin/ld: warning: libc++abi.so.1, needed by /bulk/workbench/llvm/3.7.0
/toolchain4/bin/../lib/libc++.so, not found (try using -rpath or -rpath-link)
/bulk/workbench/llvm/3.7.0/toolchain4/bin/../lib/libc++.so: undefined reference to `__cxa_rethrow_primary_exception'
/bulk/workbench/llvm/3.7.0/toolchain4/bin/../lib/libc++.so: undefined reference to `__cxa_decrement_exception_refcount'
/bulk/workbench/llvm/3.7.0/toolchain4/bin/../lib/libc++.so: undefined reference to `std::out_of_range::~out_of_range()'
[...]

The LD_LIBRARY_PATH is not set and the toolchain's install directory is added to my working PATH by:

export PATH=$PATH:/bulk/workbench/llvm/3.7.0/toolchain4/bin/

I'm on Ubuntu GNU/Linux 14.04 and I have not installed anything LLVM or Clang related packages from any repository.

According to the libc++ documentation:

On Linux libc++ can typically be used with only ‘-stdlib=libc++’. However some libc++ installations require the user manually link libc++abi themselves. If you are running into linker errors when using libc++ try adding ‘-lc++abi’ to the link line.

Doing as suggested gives a successful build.

So, my question is this:

Why do I have to specify the -lc++abi dependency explicitly on the line of the build command?

Doing

readelf -d $(llvm-config --libdir)/libc++.so

gives

Dynamic section at offset 0xb68c8 contains 31 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libc++abi.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [librt.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x000000000000000e (SONAME)             Library soname: [libc++.so.1]
 0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/../lib]
 0x000000000000000c (INIT)               0x350a8
[...]

Shouldn't the embedded RPATH in the dynamic section of the ELF be considered by ld as described in its man page under the section -rpath-link=dir?

Moreover, when I set the LD_LIBRARY_PATH with

LD_LIBRARY_PATH=$(llvm-config --libdir)

the initial build command (without specifying -lc++abi) works, as also described in the 5th clause of the aforementioned man entry.