为什么不能用的libc ++中的C ++ 0x模式链路铛此的boost :: program_options例子吗? [英] Why can't clang with libc++ in c++0x mode link this boost::program_options example?
问题描述
编译这个例子code升压:: program_options:<一href=\"http://svn.boost.org/svn/boost/trunk/libs/program_options/example/first.cpp\">http://svn.boost.org/svn/boost/trunk/libs/program_options/example/first.cpp
Compiling this example code for boost::program_options: http://svn.boost.org/svn/boost/trunk/libs/program_options/example/first.cpp
...在MacOS狮子(10.7.2),使用boost-1.48.0与MacPorts的安装:
...on MacOS Lion (10.7.2), using boost-1.48.0 installed with MacPorts:
$ clang++ -v
Apple clang version 3.0 (tags/Apple/clang-211.12) (based on LLVM 3.0svn)
Target: x86_64-apple-darwin11.2.0
Thread model: posix
$ clang++ -std=c++0x --stdlib=libc++ -lc++ -I/opt/local/include -L/opt/local/lib -lboost_program_options first.cpp -o first
Undefined symbols for architecture x86_64:
"boost::program_options::options_description::options_description(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned int, unsigned int)", referenced from:
_main in cc-6QQcwm.o
"boost::program_options::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, boost::program_options::options_description const&)", referenced from:
_main in cc-6QQcwm.o
"boost::program_options::abstract_variables_map::operator[](std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const", referenced from:
boost::program_options::variables_map::operator[](std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const in cc-6QQcwm.o
"boost::program_options::detail::cmdline::set_additional_parser(boost::function1<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>)", referenced from:
boost::program_options::basic_command_line_parser<char>::extra_parser(boost::function1<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>) in cc-6QQcwm.o
"boost::program_options::detail::cmdline::cmdline(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)", referenced from:
boost::program_options::basic_command_line_parser<char>::basic_command_line_parser(int, char const* const*) in cc-6QQcwm.o
"boost::program_options::to_internal(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > boost::program_options::to_internal<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) in cc-6QQcwm.o
"boost::program_options::invalid_option_value::invalid_option_value(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
void boost::program_options::validate<int, char>(boost::any&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, int*, long) in cc-6QQcwm.o
"boost::program_options::validation_error::validation_error(boost::program_options::validation_error::kind_t, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const& boost::program_options::validators::get_single_string<char>(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, bool) in cc-6QQcwm.o
"boost::program_options::value_semantic_codecvt_helper<char>::parse(boost::any&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, bool) const", referenced from:
vtable for boost::program_options::typed_value<int, char> in cc-6QQcwm.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
同样的code编译/与安装MacPorts的G ++ 4.7链接:
The same code compiled/linked with g++4.7 installed with MacPorts:
$ g++-mp-4.7 -std=c++0x -I/opt/local/include -L/opt/local/lib -lboost_program_options -o first first.cpp
...工作正常。由于使用铛的确没有的libc ++:
... works fine. As does using clang without libc++:
clang++ -std=c++0x -I/opt/local/include -L/opt/local/lib -lboost_program_options first.cpp -o first
有什么不对?为什么提振:: program_options或是libc ++无法一起工作?
What's wrong? Why does boost::program_options and libc++ not work together?
推荐答案
您需要使用铛++ -stdlib = ++的libc重建的推动作用。
You need to rebuild boost using clang++ -stdlib=libc++.
++的libc不是二进制用gcc的兼容的libstdc ++(除了一些低层次的东西,如运营商新的)。例如,的std ::字符串
在海湾合作委员会的libstdc ++的引用计数,而在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.
为了把这个运行时撞上一个链接时错误的libc ++使用内嵌命名空间
称为C ++ 11的语言功能改变的 ABI < /不影响的std ::字符串
的EM>的 API 的的std ::字符串
。也就是说,你的std ::字符串
看起来是一样的。不过到了链接,的std ::字符串
被损毁,如果是在空间的std :: __ 1
。因此,连接器知道的std :: basic_string的
和的std :: __ 1 :: basic_string的
是两个不同的数据结构(该从gcc的的libstdc ++,后者从libc中++)即将到来前
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++).
这篇关于为什么不能用的libc ++中的C ++ 0x模式链路铛此的boost :: program_options例子吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!