Monthly Archives: July 2012

Clang and standard libraries on Mac OS X

I’ve seen several people on the boost developers list (and the boost users list) using clang to build their programs. This generally goes pretty well; the diagnostics that clang produces are much better than gcc’s (though gcc 4.7 has made great strides in improving their error messages), but there’s a common problem when people try to turn on c++11 support.

For the first step, they just add -std=c++11 to their compiler options (Xcode configuration, makefile, command-line, whatever) to turn on c++11 language support. This generally works well for their existing code base. Then they start adding things like auto and range-based for loops, and this works great as well.

Then they start to use library features such as std::move or std::forward or #include <chrono> (and so on). And it all comes crashing down.

    ../boost/test/tools/assertion.hpp:386:36: error: no member named 'forward' in namespace 'std'
    return value_expr<T>( std::forward<T>( v ) );

The problem is that the standard library that clang uses is the gcc standard (libstdc++) library that Apple ships (which is based on gcc 4.2).

The advantage of this is that you can “mix and match” your code; compiling some parts with gcc and other parts with clang, and link them all together and they will work.

The disadvantage is that libstdc++ 4.2 predates the c++11 standard; it does not support most of the c++11 features. So, your code that uses std::forward, etc will not compile with this library, even if you turn on c++11 support in clang – this switch only controls what language the compiler will accept.

The second step that you have to do is to add -stdlib=libc++ to your command-line (Xcode settings, makefile, whatever). This tells clang to use libc++ as the standard library.

You have to tell the linker to link against libc++ instead of libstdc++ as well.

Here’s how to add a clang-11 toolset to your boost setup.┬áIn your “user-config.jam”, put this:

using clang : 11
    : "/usr/bin/clang++"
    : <cxxflags>"-std=c++11 -stdlib=libc++" <linkflags>"-stdlib=libc++""
    ;

Now you can run b2 like this b2 toolset=clang-11

On the boost list, Julian reminded me that if you’re building your clang yourself (instead of getting it through Xcode), you’ll need to get/install libc++ as well. (MacPorts is good for this)

Advertisements