2012-10-16 26 views
23

के साथ एसटीडी लिंकर त्रुटि मुझे मूल रूप से आईओएस (armv7) के लिए निर्मित उद्देश्य-सी के बिट्स के साथ सी ++ में एक बड़ी स्थिर लाइब्रेरी मिली है।ऐप्पल एलएलवीएम 4.1

मैंने ओएस एक्स (64-बिट इंटेल x86_64) संस्करण बनाया है, लेकिन जैसे ही मैंने इसे ओएस एक्स ऐप प्रोजेक्ट (शेर 10.7 पर लक्षित) में उपयोग करने का प्रयास किया, लिंकर त्रुटियों के दसियों में से अधिकांश दिखाई दिए, जिनमें से अधिकांश उन्हें मानक पुस्तकालय प्रतीकों के बारे में।

मुझे पता है कि "मेरी" लिंकर समस्याओं को कैसे हल किया जाए, लेकिन नीचे सूचीबद्ध एसटीडी मुझे परेशान कर रहे हैं।

"std::basic_filebuf<char, std::char_traits<char> >::is_open() const" 
"std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::str() const" 
"std::basic_ios<char, std::char_traits<char> >::widen(char) const" 
"std::istream& std::istream::_M_extract<double>(double&)" 
"std::ostream::put(char)" 
"std::ostream::flush()" 
"std::ostream& std::ostream::_M_insert<void const*>(void const*)" 
"std::ostream& std::ostream::_M_insert<bool>(bool)" 
"std::ostream& std::ostream::_M_insert<double>(double)" 
"std::ostream& std::ostream::_M_insert<unsigned long>(unsigned long)" 
"std::ostream::operator<<(int)" 
"std::ostream::operator<<(short)" 
"std::string::_Rep::_M_destroy(std::allocator<char> const&)" 
"std::string::_Rep::_S_terminal" 
"std::string::_Rep::_S_empty_rep_storage" 
"std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&)" 
"std::string::append(char const*, unsigned long)" 
"std::string::append(std::string const&)" 
"std::string::assign(std::string const&)" 
"std::string::reserve(unsigned long)" 
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)" 
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)" 
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()" 
"std::basic_ofstream<char, std::char_traits<char> >::open(char const*, std::_Ios_Openmode)" 
"std::basic_ofstream<char, std::char_traits<char> >::close()" 
"std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream()" 
"std::basic_ofstream<char, std::char_traits<char> >::~basic_ofstream()" 
"std::_List_node_base::hook(std::_List_node_base*)" 
"std::_List_node_base::unhook()" 
"std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(std::string const&, std::_Ios_Openmode)" 
"std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(std::_Ios_Openmode)" 
"std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::~basic_stringstream()" 
"std::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >::basic_ostringstream(std::_Ios_Openmode)" 
"std::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >::~basic_ostringstream()" 
"std::ios_base::Init::Init()" 
"std::ios_base::Init::~Init()" 
"std::basic_ios<char, std::char_traits<char> >::clear(std::_Ios_Iostate)" 
"std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)" 
"std::_Rb_tree_decrement(std::_Rb_tree_node_base*)" 
"std::_Rb_tree_increment(std::_Rb_tree_node_base const*)" 
"std::_Rb_tree_increment(std::_Rb_tree_node_base*)" 
"std::__throw_logic_error(char const*)" 
"std::__throw_length_error(char const*)" 
"std::__throw_out_of_range(char const*)" 
"std::_Rb_tree_rebalance_for_erase(std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)" 
"std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)" 
"std::cerr" 
"std::cout" 

मैं अपने निर्माण सेटिंग्स, मानक पुस्तकालय (-stdlib=libc++) को अपने प्रोजेक्ट लिंक की जाँच की और मैं अपने main.cpp में बिना किसी समस्या के std :: अदालत उपयोग कर सकते हैं।

मैंने ऐप्पल एलएलवीएम 4.1 से एलएलवीएम जीसीसी 4.2 में बिल्ड सेटिंग्स में कंपाइलर बदल दिया और समस्या गायब हो गई। मैं ऐप्पल एलएलवीएम 4.1 का उपयोग करना चाहता हूं। मैं कैसे इसे ठीक कर सकता हूं?

धन्यवाद!

+0

@gzfrancisco के रूप में, लिंक stdC++। 6.dylib इस समस्या को हल करेगा। – aksani56

उत्तर

44

मानक पुस्तकालय कि libstdc++ बजाय libc++ उपयोग करने के लिए जुड़ा हुआ है को बदलें - समस्या यह है कि अन्य पुस्तकालय जो libstdc++ लाइब्रेरी का उपयोग करता g++ मोड का उपयोग कर संकलित किया गया है।

निम्न नमूना कोड पर विचार करें:

dhcp-191:~/Development/testy/fred% cat fred.cpp 
#include <iostream> 
#include <string> 
#include "fred.h" 

using namespace std; 

bool dofred(string &x) 
{ 
    cout << x << endl; 
    return true; 
} 
dhcp-191:~/Development/testy/fred% cat fred.h 

#include <iostream> 
#include <string> 

bool dofred(std::string &x); 

dhcp-191:~/Development/testy/fred% clang++ -stdlib=libc++ -shared -o fred.dylib fred.cpp 
dhcp-191:~/Development/testy/fred% nm fred.dylib | c++filt | grep dofred 
0000000000000fa0 T dofred(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&) 
dhcp-191:~/Development/testy/fred% clang++ -stdlib=libstdc++ -shared -o fred.dylib fred.cpp 
dhcp-191:~/Development/testy/fred% nm fred.dylib | c++filt | grep dofred      
0000000000000e30 T dofred(std::string&) 

आप दो पूरी तरह से अलग निर्यात प्रतीकों मिलता है। प्रतीक का उपयोग करने का प्रयास करते समय, उसी -stdlib ध्वज का उपयोग करने वाला ऐप लिंक करने में सक्षम होगा, जबकि ऐप जो लिंक त्रुटि प्रदर्शित नहीं करेगा।

+9

आप अंतर बता सकते हैं क्योंकि libC++ std के अंदर एक इनलाइन नेमस्पेस का उपयोग करता है, इसलिए libC++ में प्रतीकों 'std :: __ 1 :: cout' की तरह हैं। – bames53

+0

@ bames53 इस तरह की लिंक त्रुटियों को ट्रैक करने के लिए यह एक महान युक्ति है! – Petesh

+0

ठीक है धन्यवाद! मुझे नहीं पता था कि 2 उपलब्ध मानक लाइब्रेरी कार्यान्वयन थे। मैं समझता हूं कि उनके पास अलग-अलग आंतरिक हैं, लेकिन मुझे नहीं लगता कि यह 'std :: cout' जैसी चीज़ों पर लिंकर मुद्दों का कारण बनता है। /संपादित करें: @ bames53 का जवाब देखा। अब मुझे पता है। थोड़ा उलझन में _why_ हालांकि :) – antho

11

सभी सी ++ फ़ाइलों को एक अलग पुस्तकालय में डालने के बाद मुझे यह समस्या थी। मैंने libC++ का उपयोग करने के लिए सभी प्रोजेक्ट की सेटिंग्स सेट की हैं, लेकिन लिंकर libC++ से लिंक नहीं है। अगर मैं मुख्य परियोजना में सी ++ फ़ाइल जोड़ता हूं, तो समस्या गायब हो जाएगी। इसे ठीक करने के लिए, आप मुख्य परियोजना के "अन्य लिंकर ध्वज" अनुभाग पर '-lC++' जोड़ सकते हैं। यह एक्सकोड को libC++ से लिंक करने के लिए मजबूर करेगा।

संपादित करें: जैसा कि अन्य पोस्टर ने कहा है, एक्सकोड सही ढंग से व्यवहार कर रहा है। मुझे उम्मीद थी कि यह C++ लिंक जोड़ने के लिए जान जाए क्योंकि C++ lib स्रोत कोड एक ही कार्यक्षेत्र पर है।

0

jlukanta के जवाब में: मुझे एक ही समस्या थी। मैं सही एसटीडी चुनने के लिए सावधान रहा हूं लेकिन मुझे अभी भी उन त्रुटियां मिली हैं। लेकिन यह एक बग नहीं है, यह वास्तव में समझ में आता है: यदि आपके प्रोजेक्ट में कोई सी ++ कोड नहीं है तो Xcode को C++ stdlib से लिंक क्यों करना चाहिए?

बेशक, यह एक समस्या है जब आपके पास अपनी परियोजना में सी ++ कोड नहीं है लेकिन फिर भी सी ++ पुस्तकालय हैं।

44

आईओएस 7 में मैं चार्ट के लिए लाइब्रेरी का उपयोग करता हूं और एक ही समस्या है। इस मामले में lib stdC++ समस्या को हल नहीं करता है।

मैं stdC++ जोड़ता हूं। 6. मेरे बिल्ड चरण में 6. डिलीब और प्रतीकों पाए जाते हैं।

+0

धन्यवाद! मुझे कई बार बचाओ! – liuyaodong

+4

यह मेरे लिए भी काम किया। क्या किसी को पता है कि क्यों 'libstdC++। Dylib' विफल रहता है और' libstdC++। 6.dylib' काम करता है? – simeon

+1

धन्यवाद, मेरे सभी बालों को बाहर खींचने से पहले यह पाया गया :) –

3

मुझे बस एक ही समस्या थी, और मुझे "बिल्ड सेटिंग्स" और फिर "ऐप्पल एलएलवीएम 5.1 - भाषा - सी ++" पर जाना पड़ा और फिर "सी ++ मानक लाइब्रेरी" को libstdC++ में बदलना पड़ा।

1

आप अपनी परियोजना में खाली .cpp फ़ाइल जोड़ने का भी प्रयास कर सकते हैं।यह सी ++ एसडीडी पुस्तकालयों को लोड करने में एक्सकोड को ट्रिक करेगा

+1

धन्यवाद! यह एकमात्र समाधान है जो मेरे लिए काम करता है। मैंने libC++ और libstdC++ (एलएलवीएम सी ++ और "अन्य लिंकर फ्लैग" बिल्ड सेटिंग्स में निर्दिष्ट) के साथ जोड़ने का प्रयास किया, लेकिन कोई भाग्य नहीं ... प्रोजेक्ट में एक खाली "foo.cpp" फ़ाइल और वॉयला, कोई और लिंकर त्रुटियां नहीं जोड़ा! धन्यवाद! –