2011-12-10 7 views
60

बढ़ावा :: program_options के लिए इस उदाहरण कोड संकलन: http://svn.boost.org/svn/boost/trunk/libs/program_options/example/first.cppसी ++ 0x मोड में libC++ के साथ क्यों नहीं जोड़ा जा सकता है इस boost :: program_options उदाहरण?

... MacOS शेर पर (10.7.2), को बढ़ावा देने-1.48.0 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) 

एक ही कोड संकलित/मैकपोर्ट्स के साथ जी ++ 4.7 के साथ जुड़ा हुआ है:

$ g++-mp-4.7 -std=c++0x -I/opt/local/include -L/opt/local/lib -lboost_program_options -o first first.cpp 

... ठीक काम करता है। LibC++:

clang++ -std=c++0x -I/opt/local/include -L/opt/local/lib -lboost_program_options first.cpp -o first 
clang++ -std=c++0x -I/opt/local/include -L/opt/local/lib -lboost_program_options first.cpp -o first 

क्या गलत है? Boost :: program_options और libC++ एक साथ क्यों काम नहीं करते हैं?

+3

ऐसा लगता है कि आपके लिंकर को उचित 64-बिट libs नहीं मिल रहा है। "एलडी: आर्किटेक्चर x86_64" –

उत्तर

129

आपको क्लैंग ++ -stdlib = libC++ का उपयोग करके बढ़ावा देने के लिए पुनर्निर्माण की आवश्यकता है।

libC++ जीसीसी के libstdC++ के साथ बाइनरी संगत नहीं है (ऑपरेटर के रूप में कुछ निम्न स्तर की सामग्री को छोड़कर)। उदाहरण के लिए gcc के libstdC++ में std::string को refcounted है, जबकि libC++ में यह "शॉर्ट स्ट्रिंग अनुकूलन" का उपयोग करता है। यदि आप एक ही प्रोग्राम में इन दो तारों को गलती से मिश्रण करना चाहते थे (और उन्हें एक ही डेटा संरचना के लिए गलती), तो आपको अनिवार्य रूप से रन टाइम क्रैश मिल जाएगा।

यह दुर्घटना ठीक है जो आपके मामले में हुई है।

आदेश एक लिंक टाइम त्रुटि में इस रन टाइम दुर्घटना बारी करने के लिए, libC++ एक सी ++ 11 भाषा inline namespace बुलाया एपीआई को प्रभावित std::string की बिना std::string की ABI बदलने के लिए सुविधा का उपयोग करता। यही है, आप std::string वही दिखते हैं। लेकिन लिंकर को, std::string को उलझाया जा रहा है जैसे कि यह नामस्थान std::__1 में है। इस प्रकार लिंकर जानता है कि std::basic_string और std::__1::basic_string दो अलग-अलग डेटा संरचनाएं हैं (पूर्व में जीसीसी के libstdC++ से आ रहा है और बाद वाला libC++ से आ रहा है)।

+5

पीएस के लिए प्रतीक नहीं मिला क्लैंग/libC++ के लिए बूस्ट को पुन: कंपाइल कैसे करें: http://stackoverflow.com/questions/8486077/how-to-compile-link-boost-with-clang-libc –

+0

महान उत्तर के लिए धन्यवाद! –

+0

एक त्वरित सवाल। अगर मैं my_stdlib_str.c_str() कर रहा था तो मुझे अंततः गलती मिल जाएगी, है ना? मेरा मतलब है कि लिंकर चाल के ऊपर उस मामले में पारित किया जाएगा? – ShitalShah