If you read the release announcement, then you’ll have seen that there is a new C++ stack in 9.1, but that it is marked optional and is not part of the default binary install. If you’re a C++ developer, you may want to play with it for a few reasons:
- It supports C++11 (which is new, shiny, and buzzwordy)
- It will be the only one shipped by default in 10.0, so if you care about forward compatibility then you will need to test with it or make sure that your code works with it, or depend on GNU libstdc++ from ports.
The new stack uses libcxxrt, which I originally wrote for PathScale and was since open sourced (funded by the FreeBSD and NetBSD Foundations). This implements the low-level part of the C++ standard library, providing things like support for RTTI,
dynamic_cast, exceptions, thread-safe initialisation of statics, and so on. In the old stack, libsupc++ does this.
On top of this sits the STL implementation. In the old stack, this was GNU libstdc++, in the new one it’s LLVM’s libc++. To make interoperability easier, in 9.1 we have made libstdc++ dynamically link against libsupc++. You can use
libmap.conf(5) to tell it to link against libcxxrt instead, and then you can mix libraries that use libc++ with ones that use libstdc++ in the same program.
The new stack isn’t installed by default, but building and installing it is very easy:
# cd /usr/src/lib/libcxxrt # make # make install # cd ../libc++ # make CXX=clang++ # make install
You should now have
libc++.so installed in
/usr/lib and the headers installed in
/usr/include/c++/v1. You are now ready to compile C++ code with the new stack. You use them, clang has a command-line switch for selecting the stack to use. By default, it will still use the old stack:
$ clang++ hello.cc $ ./a.out Hello C++ World $ ldd ./a.out ./a.out: libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x800819000) libm.so.5 => /lib/libm.so.5 (0x800b29000) libc.so.7 => /lib/libc.so.7 (0x800d4a000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x80109d000)
To enable the new stack, you must add
-stdlib=libc++ to your
CXXFLAGS and also to your
LDFLAGS. The first ensures that we get the libc++ headers, the second that we link to libc++:
$ clang++ -stdlib=libc++ -std=c++11 hello.cc $ ./a.out Hello C++ World $ ldd ./a.out ./a.out: libc++.so.1 => /usr/lib/libc++.so.1 (0x80081a000) libm.so.5 => /lib/libm.so.5 (0x800ac9000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x800cea000) libc.so.7 => /lib/libc.so.7 (0x800ef7000) libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x80124a000)
Unfortunately, in 9.1 there is a small bug that prevents you from compiling in C++98 mode with libc++. The C11
at_quick_exit() functions are exposed in our
stdlib.h only in C11 and C++11 modes, but are referenced in libc++’s
cstdlib in any mode.
Most code should work out-of-the-box in C++11 mode though, so there’s little reason not to try it. And, because of the availability of move semantics, some code using STL classes will be more efficient when compiled in C++11 mode.
If you want to test with a newer version, but don’t want to install -CURRENT, I’m putting x86-64 binaries of libc++ back-ported to 9.1 online for testing. I’ll update this whenever I pull a new version into -CURRENT.