<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    Hi,<br>
    <br>
    I'm currently setting up a fresh Linux box (recent Mint, using GCC
    4.8 as system compiler) as a dev environment, and since my stuff is
    using cutting-edge C++, I want Clang and libc++ for this.
    Unfortunately, getting this to work isn't fun at all.<br>
    <br>
    Clang itself is easy.<br>
    <br>
    libc++ is anything but. Reading the instructions provided[1], it
    looks very much like building with libsupc++, pulled out of the
    libstdc++.so, is the best way of doing things. Using libcxxrt (or
    libc++abi, but why would I do that on Linux) is listed as having a
    little drawback: "Unfortunately you can't simply run clang with
    "-stdlib=libc++" at this point, as clang is set up to link for
    libc++ linked to libsupc++."<br>
    <br>
    Therefore I go with this CMake command line:<br>
    <br>
    <code>CC=clang CXX=clang++ cmake -G Ninja -DLIBCXX_CXX_ABI=libstdc++
-DLIBCXX_LIBSUPCXX_INCLUDE_PATHS="/usr/include/c++/4.8/;/usr/include/</code><code><code>x86_64-linux-gnu/</code>c++/4.8/"

      -DCMAKE_BUILD_TYPE=Release <libc++-source-dir></code><br>
    <br>
    Note that I removed the install prefix so it defaults to /usr/local.
    This means I need an ldconfig update after installing, but that part
    works. Also, my Clang sits in /usr/local, so the header search path
    setup in Clang does the right thing. I'm also using Ninja, but I
    tested and it doesn't change anything compared to Makefiles.<br>
    <br>
    After building and installing, I try to compile a small example
    program that uses dynamic_cast and iostreams.<br>
    <br>
    <font face="monospace">#include <iostream><br>
      struct Base { virtual ~Base() {} };<br>
      struct Derived : Base {<br>
        void x() { std::cout << "Hello, World!\n"; } <br>
      };<br>
      void foo(Base& b) {<br>
        dynamic_cast<Derived&>(b).x();<br>
      }<br>
      int main() {<br>
          Derived d;<br>
          foo(d);<br>
      }</font><br>
    <br>
    And I compile it using<br>
    <br>
    <font face="monospace">$ clang++ -stdlib=libc++ -o hello-llvm
      hello.cpp</font><br>
    <br>
    This fails:<br>
    <br>
    <font face="monospace">/usr/bin/ld: /tmp/hello-7f7d71.o: undefined
      reference to symbol '__cxa_free_exception@@CXXABI_1.3'<br>
      /usr/lib/x86_64-linux-gnu/libstdc++.so.6: error adding symbols:
      DSO missing from command line<br>
      clang-3.5: error: linker command failed with exit code 1 (use -v
      to see invocation)</font><br>
    <br>
    Here's the problem: when building libc++, the linker finds the
    various ABI functions in libstdc++, and is quite happy with them
    being there. When Clang calls the linker for the actual program,
    though, it doesn't pass along a link flag for libstdc++, only for
    libc++. Thus, the links fails.<br>
    <br>
    Ironically enough, I can't even manually add -lstdc++ to the command
    line: Clang recognizes this as an attempt to link the standard
    library and replaces with with -lc++ - so the final link command has
    two -lc++ flags and the link fails with the same error. I have to
    give the full path to the library as an input file to make it work.
    This is not a good situation.<br>
    <br>
    If we strike the goal of having only one copy of the C++ ABI stuff
    in the final program, even if it links to a C++ library using
    libstdc++, then we have more options. Using libcxxrt is on the
    table, and so is linking against the static libsupc++ library. The
    latter shouldn't use any additional command line flags, so let's try
    this:<br>
    <br>
    <code>CC=clang CXX=clang++ cmake -G Ninja -DLIBCXX_CXX_ABI=libsupc++
-DLIBCXX_LIBSUPCXX_INCLUDE_PATHS="/usr/include/c++/4.8/;/usr/include/</code><code><code>x86_64-linux-gnu/</code>c++/4.8/"

      -DCMAKE_BUILD_TYPE=Release <libc++-source-dir></code><br>
    <br>
    This doesn't work either for some reason:<br>
    <br>
    <font face="monospace">$ clang++ -stdlib=libc++ -o hello-llvm
      hello.cpp<br>
      /tmp/hello-3689e5.o: In function `foo(Base&)':<br>
      hello.cpp:(.text+0x39): undefined reference to `__dynamic_cast'<br>
      hello.cpp:(.text+0x4e): undefined reference to `__cxa_bad_cast'<br>
      clang-3.5: error: linker command failed with exit code 1 (use -v
      to see invocation)</font><br>
    <br>
    Using nm to inspect libc++.so, it appears that the linker just
    doesn't pull in (or at least export) these two functions. This, in
    turn, is probably because it doesn't use them (libc++ doesn't use
    dynamic_cast in any compiled code; there's one use in the inline
    rethrow_exception, one in the template dynamic_pointer_cast, and one
    in an unevaluated context in type_traits). Neither is there any
    linker input instructing the linker to pull in the symbol, or an
    appropriate use of --whole-archive.<br>
    <br>
    This again can be worked around by explicitly specifying linking
    against the source library, and here -lsupc++ works.<br>
    <br>
    <br>
    The bottom line is that none of the libc++ options on Linux work out
    of the box without additional command line arguments beyond
    -stdlib=libc++, and the best option (libstdc++, which prevents
    duplication of the ABI stuff in a process) is actually the worst
    case, because -lstdc++ doesn't work as a workaround.<br>
    <br>
    <br>
    This makes me unhappy. So I did some research into possible
    solutions.<br>
    <br>
    The libsupc++ problem is independent of the others. It basically
    comes down to using --whole-archive to pull in libsupc++.a
    completely into the resulting .so, not just the parts that happen to
    be used. A patch hacking the CMakeLists.txt to do exactly that is
    attached.<br>
    <br>
    <br>
    The other problem is this: how do we make it so that no additional
    command line flags are required, no matter what ABI library is used?
    Ideally, the libc++.so would just tell the linker to pull the ABI
    library into the link, or claim to export the symbols itself but
    really just forward to the underlying library.<br>
    <br>
    The first solution is exactly what libtool does, but using the
    wrapper isn't really an option, not to mention that it would require
    writing the libtool specs manually or using libtool to build libc++.
    Neither of these are attractive options. The linker itself does not
    have any way of doing this, even though reading the documentation
    for --rpath-link makes it sound like it does.<br>
    <br>
    The second solution is what is done on MacOS. The MachO linker
    supports the reexport_library option. Similarly, PE/COFF DLLs on
    Windows support such forwarding symbols (kernel32.dll contains lots
    of forwarders to ntdll.dll); an OldNewThing article[2] describes
    this and the comments contain links to more detailed information.<br>
    <br>
    It appears, however, from my reading of the ld man page and
    extensive web searching, that there is no way to do the equivalent
    thing on Linux without actually adding stub forwarders to the
    library in question. I have asked on StackOverflow[3], but I don't
    really expect an answer.<br>
    <br>
    So it seems there are these options:<br>
    <br>
    1) Add stub forwarders to libc++. This is annoying, but it works
    with libc++ modifications alone.<br>
    2) Have Clang find out by some means what flags, beyond -lc++, are
    needed to link against libc++. This information would have to be
    provided by libc++ somehow.<br>
    3) Have the user tell Clang. For example, -stdlib=libc++ could
    instead be -stdlib=libc++-gnuabi or -stdlib=libc++-cxxrt, depending
    on the ABI lib. Or the ABI could be a separate option, i.e.
    -stdlib=libc++ -abilib=cxxrt. Of course, this is little better than
    the state we have now.<br>
    <br>
    Any thoughts on this? Preferred variant? Things I've overlooked?<br>
    <br>
    <br>
    [1] <a class="moz-txt-link-freetext" href="http://libcxx.llvm.org/">http://libcxx.llvm.org/</a><br>
    [2]
    <a class="moz-txt-link-freetext" href="http://blogs.msdn.com/b/oldnewthing/archive/2006/07/19/671238.aspx">http://blogs.msdn.com/b/oldnewthing/archive/2006/07/19/671238.aspx</a><br>
    [3]
<a class="moz-txt-link-freetext" href="http://stackoverflow.com/questions/22764734/linux-equivalent-of-windows-dll-forwarders-or-macos-reexport-library">http://stackoverflow.com/questions/22764734/linux-equivalent-of-windows-dll-forwarders-or-macos-reexport-library</a><br>
  </body>
</html>