Why can't clang with libc++ in c++0x mode link this boost::program_options example?
You need to rebuild boost using clang++ -stdlib=libc++.
libc++ is not binary compatible with gcc's libstdc++ (except for some low level stuff such as operator new). For example the std::string
in gcc's libstdc++ is refcounted, whereas in libc++ it uses the "short string optimization". If you were to accidentally mix these two strings in the same program (and mistake them for the same data structure), you would inevitably get a run time crash.
This accident is exactly what has occurred in your case.
In order to turn this run time crash into a link time error, libc++ uses a C++11 language feature called inline namespace
to change the ABI of std::string
without impacting the API of std::string
. That is, to you std::string
looks the same. But to the linker, std::string
is being mangled as if it is in namespace std::__1
. Thus the linker knows that std::basic_string
and std::__1::basic_string
are two different data structures (the former coming from gcc's libstdc++ and the latter coming from libc++).
Linking troubles with boost::program_options on OSX using LLVM
You will need to recompile boost with clang and std11 flags, the libc++ library is not binary compatible with the installed libstdc++ in OSX (very early version of gcc prior to changing to gpl3). If your version of clang is 3.1 or over then you can use (otherwise change c++11 to c++0x for earlier versions).
./bootstrap.sh
mkdir build
sudo ./bjam toolset=clang cxxflags="-std=c++0x -stdlib=libc++" variant=release link=static threading=multi runtime-link=shared --build-dir=Build --layout=system --without-mpi --without-python install --prefix=/usr/local
You can of course alter any of these as you wish except
toolset=clang cxxflags="-std=c++0x -stdlib=libc++"
This should work for you.
How to compile/link Boost with clang++/libc++?
I didn't know how to do this either. But after poking around in here, the getting started, and trial and error:
$ ./bootstrap --with-toolset=clang
$ ./b2 clean
$ ./b2 toolset=clang cxxflags="-stdlib=libc++" linkflags="-stdlib=libc++"
You'll get lots of warnings. And the signals library will fail to build due to LWG 2059. But otherwise I think it works.
Linking troubles with boost::program_options on OSX using LLVM
You will need to recompile boost with clang and std11 flags, the libc++ library is not binary compatible with the installed libstdc++ in OSX (very early version of gcc prior to changing to gpl3). If your version of clang is 3.1 or over then you can use (otherwise change c++11 to c++0x for earlier versions).
./bootstrap.sh
mkdir build
sudo ./bjam toolset=clang cxxflags="-std=c++0x -stdlib=libc++" variant=release link=static threading=multi runtime-link=shared --build-dir=Build --layout=system --without-mpi --without-python install --prefix=/usr/local
You can of course alter any of these as you wish except
toolset=clang cxxflags="-std=c++0x -stdlib=libc++"
This should work for you.
clang++ -stdlib=libc++ leads to undefined reference
According you error, it should be like you're trying to link a libc++ with stdlibc++,
the libc++ and stdlibc++ is different, stdlibc++ is gcc's c++ standard library, it will not compatible with each other.
For your issue, it's like your libpoppler.so is using stdlibc++,
but in your clang command line, you're trying use libc++ as standard lib, they have different name in linking stage, see link at the end of this answer for detail why.
So, maybe your solution is just change the compile command to
clang++ -stdlib=libstdc++ po.cxx -lpoppler
Please see this question for detail why std:__1::set and std::set.
Why can't clang with libc++ in c++0x mode link this boost::program_options example?
Does boost use C++11 inline namespaces to avoid ABI incompatibilty errors at runtime?
Some libraries have started to use it, but not all. For example this is in Boost.Log:
//! NOTE: I've reformatted this to look cleaner.
#if !defined(BOOST_NO_CXX11_INLINE_NAMESPACES)
inline namespace BOOST_LOG_VERSION_NAMESPACE {}
[snip]
#endif
How to use boost::program_options to accept an optional flag?
A convenient way to do this is with the bool_switch
functionality:
bool flag = false;
namespace po = boost::program_options;
po::options_description desc("options");
desc.add_options()
("flag,f", po::bool_switch(&flag), "description");
po::variables_map vm;
//store & notify
if (flag) {
// do stuff
}
This is safer than manually checking for the string (string only used once in whole definition).
Related Topics
What's Your Favorite Profiling Tool (For C++)
In C/C++ What's the Simplest Way to Reverse the Order of Bits in a Byte
Calculating Normals in a Triangle Mesh
How to Get the Error Message from the Error Code Returned by Getlasterror()
How to Implement Make_Unique Function in C++11
Do Unused Functions Get Optimized Out
Iterate Vector, Remove Certain Items as I Go
Is There a Reason to Call Delete in C++ When a Program Is Exiting Anyway
When Using C Headers in C++, Should We Use Functions from Std:: or the Global Namespace
Createprocess from Memory Buffer
Multi Line Preprocessor Macros
Convert Cstring to Const Char*
How to Parse a Date String into a C++11 Std::Chrono Time_Point or Similar