Clang 3.1: Can't link Hello World-program program on Linux

Hello,
I am currently trying to build a Hello World-program on Fedora 16 using
Clang from Subversion:

clang version 3.1 (trunk 151711)
Target: x86_64-unknown-linux-gnu
Thread model: posix

When building without "--stdlib=libc++", I run into compile-time-errors
in the GNU implementation of the IOstream library.
So I built libc++ (with the above compiler), using the workaround
suggested in this thread:
http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-February/019910.html

With the "--stdlib=libc++" option, the linking of the program fails,
asking for some symbols from the CXXABI:

$ clang++ --stdlib=libc++ -o helloworld helloworld.cpp
/usr/bin/ld: /tmp/helloworld-Jxd2ZV.o: undefined reference to symbol
'__cxa_begin_catch@@CXXABI_1.3'
/usr/bin/ld: note: '__cxa_begin_catch@@CXXABI_1.3' is defined in DSO
/usr/lib64/libstdc++.so.6 so try adding it to the linker command line
/usr/lib64/libstdc++.so.6: could not read symbols: Invalid operation
clang-3: error: linker command failed with exit code 1 (use -v to see
invocation)

What did I do wrong? Is Clang or libcxx misconfigured, or is this a
compiler bug? How could I fix or work around the issue?

I'd love to use Clang for some testing of C++11, since it gained a lot
support recently (thanks a lot by the way! Kudos to Clang hackers!).

Alexander

libc++ does not provide the ABI layer, just the STL layer. You need another library for the ABI. You may be able to link to libstdc++ and get libsupc++ indirectly. Alternatively, try using libcxxrt:

https://github.com/pathscale/libcxxrt/

David

libc++ does not provide the ABI layer, just the STL layer.

Ok, I did not know that.

You need another library for the ABI. You may be able to link to

libstdc++ and get libsupc++ indirectly.
That doesn't work, I get the same linking error. Apparently the linker
is trying to include libstdc++, but fails with
"could not read symbols: Invalid operation"

Alternatively, try using libcxxrt:

https://github.com/pathscale/libcxxrt/

Thanks, linking with libcxxrt works! Now I can try the compiler. However
it works only dynamically, and I have to pass
"-ldl -lcxxrt --stdlib=libc++" to every compile.

I know integration with GCC's headers and libraries must be difficult,
but shouldn't it be easier to obtain a working version of Clang?

Alexander

You shouldn't need to do this, just link libc++ against libcxxrt (which should link against libdl on Linux).

David

There is also now a llvm equivalent to libcxxrt here:

http://libcxxabi.llvm.org/

Howard

As mentioned in a different thread, make sure that libc++ is compiled
with -DLIBCXXRT or e.g. std::cerr will not work.

Joerg

How do I do this?

When I add "-lcxxrt" or "-l:libcxxrt.a" to the linker command line of
libc++, the linking of libc++ succeeds.
But then, when compiling helloworld, symbols are missing unless I
excplitly specify '-lcxxrt'.
Shouldn't linking libc++ against libcxxrt pull that in automatically?

By the way, libc++abi does not compile because of the issue described
here: http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-February/019906.html

Alexander

Alexander Korsunsky
<fat.lobyte9-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> writes:

[...]

You shouldn't need to do this, just link libc++ against libcxxrt (which should link against libdl on Linux).

How do I do this?

When I add "-lcxxrt" or "-l:libcxxrt.a" to the linker command line of
libc++, the linking of libc++ succeeds.
But then, when compiling helloworld, symbols are missing unless I
excplitly specify '-lcxxrt'.
Shouldn't linking libc++ against libcxxrt pull that in automatically?

Really? It worked for me, after a few stumbles. I needed to build
libcxxrt with clang and clang++ adding -fPIC to C_FLAGS and CXX_FLAGS
(otherwise libcxxrt.a isn't suitable for linking into the shared
libc++).

Then I built libc++, adding -DLIBCXXRT to EXTRA_FLAGS and libcxxrt.a to
the link line. Then at least a Hello World seems to work, and the
executable doesn't drag in libstdc++.

I had to create a link to libc++.so.1 from /usr/lib (I installed it into
/usr/local/lib, but that doesn't seem to be searched, even though clang
is in /usr/local/bin), and the headers have to be in
/usr/local/lib/clang/3.1. If you don't get the headers in the right
place your clang may pick up g++ headers and that'll cause problems.

[...]

In FreeBSD trunk, we have libc++.so dynamically linked against libcxxrt.so (so that eventually we can link libstdc++.so against it and - with some care - mix libraries linked against both. It hasn't been extensively tested, but compiling things with -stdlib=libc++ seems to work without needing any extra flags.

David

David Chisnall <csdavec-NvTk+tks62u1Qrn1Bg8BZw@public.gmane.org> writes:

[...]

In FreeBSD trunk, we have libc++.so dynamically linked against
libcxxrt.so (so that eventually we can link libstdc++.so against it
and - with some care - mix libraries linked against both. It hasn't
been extensively tested, but compiling things with -stdlib=libc++
seems to work without needing any extra flags.

That ought also to work, depending on the linker. (ISTR having issues
with doing this kind of thing with gold, for example.) But anyway, just
building with -fPIC seems to work fine.

Ah, except for std::uncaught_exception, come to think of it: I found
that given as duplicately defined (in libcxxrt and libc++). Removing the
libcxxrt definition resolved that.

Ok, I finally figured out how get a working standard library, using
libc++, libc++abi and libunwind. This is how I did it:

1. Download libunwind from here:
Downloading libunwind and unpack it.

2. Download libc++abi from here: http://libcxxabi.llvm.org/
Go into the lib directory, and trick the build script into using the
libunwind/include directory, for example with the CPATH environment
variable. Compile libc++abi with the build script and (manually) install
the resulting libraries.

3. Download libc++ from here: http://libcxx.llvm.org/
Configure it to link against libc++abi by adding the "-lc++abi" flag to
the CMake variable "CMAKE_SHARED_LINKER_FLAGS".
Build libc++.
Add the libcxxabi/include directory to the include directories, for
example by adding "-I/path/to/libcxxabi/include" to the Cmake variable
"CMAKE_CXX_FLAGS".
Compile libc++

Now I had a more or less working standard library. One issue remains: I
have to manually add "-lc++abi" to every compiler invocation, because
this libary is not linked by default.

Ok, here comes suggestion time:

1) Maybe I didn't go the optimal way, but to me it seemed pretty darn
hard to get the compiler working.
Although Clang and libc++ and libc++abi are different projects, it would
be really nice if one didn't have to go through setting them up and
compiling manually.
Once libc++/libc++abi reach a good level of maturity they should be
integrated into (or at least shipped with) Clang.

A "drop in"-replacement for GCC was not possible, because the libstdc++
headers caused compile errors, so libc++ had to be used.

2) Please solve the thingy with the missing <unwind.h> on linux:
http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-February/019906.html

3) Please add a flag to link with the right library "-lc++abi" to the
linker command line in the compiler driver, if "-stdlib=libc++" was
specified. Maybe it is possible to check the dependencies of libc++
(like ldd?), and add the correct library to the command line.

I think this concerns tools/clang/lib/Driver/Tools.cpp around line 4700.

4) Please, oh please document libc++ and libc++abi properly. It was a
nice guessing game of how to properly build/install the stuff or which
dependencies to use.

That being said, I really look forward to your compiler being more
adopted in the Linux and Windows world. Diagnostics are a lot better,
and the whole project looks a lot cleaner/saner than GCC. Even
C++11-Support caught up!

Please keep up the good work and thanks for what you already achieved!

Regards, Alexander

This would be the wrong thing to do in almost all situations. We are using libc++ with libcxxrt on Solaris and FreeBSD - adding -lc++abi would be just plain wrong (because we're not using libc++abi), and adding -lcxxrt is redundant because it is linked by libc++ so you don't need to link it twice.

Oh, and the missing unwind.h is not a problem if you are using libcxxrt either. It includes the required headers.

David

Right. The normal configuration should be to use the target platform's ABI library; switching to libc++abi is a distro-maintainer decision more than it is an end-programmer decision. For GNU/Linux, this library is libsupc++. I don't know off-hand how well libc++ builds or runs on top of that, but I think bugs and patches (especially patches!) would be welcome, unless that would run us afoul of licensing in some bizarre way.

John.

https://github.com/pathscale/path64-suite

That repo solves every request you had and with some tweaks could be used for clang/libc++. All the things you're trying to build are really tightly intertwined - Trying to hodgepodge them together isn't the way to go at all (As you and others have found out) Our README is very clear about what's been tested to work together. The first step is probably getting the repo that work together clearly documented. After that you'll likely need some parent or wrapper project which builds things correctly. If someone makes a patch for it to cleanly work with clang or libc++ we'll apply it.

Best,

./C