Question

I have just downloaded clang 3.3 (homebrew) from the LLVM web page to my mac (OS X 10.8.4), but get this compiler error when using std=c++11 stdlib=libc++:

In file included from /usr/include/c++/v1/string:434:
In file included from /usr/include/c++/v1/algorithm:594:
In file included from /usr/include/c++/v1/memory:590:
In file included from /usr/include/c++/v1/typeinfo:61:
/usr/include/c++/v1/exception:146:5: error: an attribute list cannot appear here
    _LIBCPP_NORETURN friend void rethrow_exception(exception_ptr);
    ^~~~~~~~~~~~~~~~
/usr/include/c++/v1/__config:190:28: note: expanded from macro '_LIBCPP_NORETURN'
#  define _LIBCPP_NORETURN [[noreturn]]
                           ^~~~~~~~~~~~

It seems that I also need another libc++ (even though it was said that it was 100% complete on MAC ...), but I cannot find any. Any help appreciated. Just for your info:

> clang++ -v
clang version 3.3 (tags/RELEASE_33/final)
Target: x86_64-apple-darwin12.4.0
Thread model: posix

And, yes, I googled it and found this: http://comments.gmane.org/gmane.comp.compilers.llvm.bugs/24138 claiming it's resolved in libc++ trunk ???


Okay, as suggested by Howard, I've downloaded tip-of-the-trunk libc++ into /opt/local/share/libcxx, but have trouble building it. The manual says to cd libcxx/lib, export TRIPLE=-apple-, and run ./buildit. I presume this implies bash (I'm usually a tcsh user, so I moved my .tcshrc, got a new shell and started bash). I did that and the compilations worked, but the library build failed. Apparently ./buildit doesn't see $TRIPLE=-apple-, as it picks the wrong LDSHARED_FLAG (not that on line 81, but that on line 103, which is to be used if $TRIPLE is not set), even though echo $TRIPLE yields -apple- as it should. When I add the statement echo TRIPLE = $TRIPLE at the top of buildit, it reports nothing. How come? What is wrong here?


The failure was that because the wrong LDSHARED_FLAG was picked the loading didn't work (ld complaint about the unknown option -soname which, I think, makes sense under linux). I don't know why buildit (a #! /bin/sh file) didn't pick up the TRIPLE environment variable (it did pick up several unwanted ones such as CXX and CC). I now simply added TRIPLE=-apple- at the top of that file and it did built the library. However, the loader spitted out several warnings all of which were of the form

ld: warning: direct access in ___cxa_bad_typeid to global weak symbol typeinfo for std::bad_typeid means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.

But most importantly, it works (the compilation at least, I have yet to test the library). I have one final question. The advice was to use -I and -L to tell the compiler about the whereabouts of this version. Is it not possible to put it into the usual place /usr/include/c++/v1/? Note that Xcode has its version somewhere else anyway and I had put in a symbolic link (/usr/include/c++/v1/) to that one to get my homebrew clang 3.2 working (after the some Xcode update). What about the library? Can I also put it in a standard place?

Was it helpful?

Solution

Here is the home page of libc++:

http://libcxx.llvm.org

You can download the tip-of-trunk libc++ from there. You can tell clang to point to your download with -nostdinc++ -I<path-to-libc++>/include. You can also tell clang to link to your tip-of-trunk libc++ with -L<path-to-libc++>/lib and export DYLD_LIBRARY_PATH=<path-to-libcxx>/lib. The directions are all on the libc++ home page.

Xcode is the easiest way to get clang + libc++. But if you want the very latest, this is the place to go.


Congratulations!

Don't worry about the ld warning. It is a harmless ld bug that will be fixed in a future release. I see it on 10.8.4 too and it doesn't hurt anything.

The libc++ headers no longer live at /usr/include/c++/v1. Xcode has migrated them into itself. Having libc++ headers at /usr/include/c++/v1 from older installs has been a source of confusion and bugs. I regularly use -nostdinc++ -I to point to the libc++ headers I want (I often have several versions going at the same time), and that works well for me.

It is possible for you to replace your /usr/lib/libc++.1.dylib with that you have built. I do not recommend doing this. I have to sometimes to do a proper test, but I always do so very carefully because sometimes this causes me to have to reboot onto a backup disk and restore my /usr/lib to its original state. If you do go this route, it is a very good idea to have a backup of the original /usr/lib/libc++.1.dylib very handy.

I recommend instead -L on the command line, and export DYLD_LIBRARY_PATH=<path-to-libcxx>/lib in the shell. More than one person (including myself) has gotten their computer into a really nasty place by not following this advice.

If you run testit (under test/), all you need is DYLD_LIBRARY_PATH in that shell. The testit script is set up to point to the right places without an install.

Also I recommend figuring out why you had to modify buildit. No one else is seeing that behavior. printenv on your command line may help in this endeavor.

libc++ is updated often. We try to keep tip-of-trunk always in a shippable state.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top