How do I compile boost for OS X 64b platforms with stdlibc++?

boost, c++, clang, libstdc++, macos

Solution

Downloaded Boost 1.55, bootstrapped using:

./bootstrap.sh --prefix=/usr/local/boost155 cxxflags="-arch i386 -arch x86_64" \
    address-model=32_64 threading=multi macos-version=10.8 stage

Built using:

./b2 threading=multi link=static runtime-link=static \
    cxxflags="-stdlib=libstdc++" linkflags="-stdlib=libstdc++"

Yields in `libboost_chrono.a`:

     U std::string::_Rep::_M_destroy(std::allocator<char> const&)
     U std::string::_Rep::_S_empty_rep_storage
     U std::string::append(char const*, unsigned long)
     U std::string::append(std::string const&)
     U std::string::assign(char const*, unsigned long)
     U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)
     U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)

Which implies that the library was built with the option `-stdlib=libstdc++` - i.e. it's linked against the gnu version of the C++ runtime.

We purge the build using:

find . -name \*.o -print0 | xargs -0 rm
find . -name \*.a -print0 | xargs -0 rm

If we don't do that then it doesn't rebuild, and you end up with the same code as before. Next we build using:

./b2 threading=multi link=static runtime-link=static \
    cxxflags="-stdlib=libc++" linkflags="-stdlib=libc++"

Yields in `libboost_chrono.a`:

     U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::append(char const*)
     U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::append(char const*, unsigned long)
     U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::assign(char const*)
     U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
     U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()

Which implies that it's built against `libc++`.

This can be verified by using a simple test c++ program (to indicate the linking):

#include <string>

int
main(int argc, char **argv)
{
    std::string s("Hello World");
    return 0;
}

$ make test
c++     test.cpp   -o test
$ nm ./test | c++filt
                 U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(char const*, unsigned long)
                 U std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()

$ rm test
$ make test CXXFLAGS=-stdlib=libstdc++
c++ -stdlib=libstdc++    test.cpp   -o test
$ nm ./test | c++filt
                 U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)
                 U std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()

so yes, it's compiling with the relevant flag. What it does indicate that you have to pass the `-stdlib=libstdc++` to everything you're compiling if you're using XCode 5 as it now defaults to using `-stdlib=libc++`. This means that any C++ based libraries that depend on `c++` stdlib that you depend on also have to be compiled with the same flag.

Be careful with an incremental build of boost - if you don't purge the `.o` and `.a` files, they don't get recompiled based on the changed flags, which keeps the files as compiled, so if they were miscompiled then you encounter the problem.

Problem

I would like to compile boost for Mac OS X 10.9, with stdlibc++. I run the following command: ``` ./b2 threading=multi link=static runtime-link=static cxxflags="-stdlib=libstdc++" linkflags="-stdlib=libstdc++" ``` The build completes successfully; however, my application build fails at linkage time, when it can't find symbols suck as std::__1::locale::use_facet, std::__1::basic_string etc. The pertinent detail there is the __1, I believe. My question is, how do I compile boost for OSX 64b platforms with stdlibc++? More info: I have noticed the following logs during compilation: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: bin.v2/libs/filesystem/build/clang-darwin-4.2.1/release/link-static/runtime-link-static/threading-multi/libboost_filesystem.a(windows_file_codecvt.o) has no symbols

Original source