2017-07-31 11 views
8

हमें लिनक्स के लिए संकलित कुछ पुस्तकालय (.a) प्राप्त हुए हैं (शायद जीसीसी 6.x के साथ संकलित)।_GLIBCXX_USE_CXX11_ABI, जीसीसी 4.8 और एबीआई संगतता

हम जीसीसी 4.8 का उपयोग कर रहे हैं और हमें लिंक की कोशिश करते समय टाइप की त्रुटि मिल रही है: undefined reference to std::__cxx11::basic_string

आम तौर पर यह सुनिश्चित करके यह तय किया जा सकता है कि सभी इकाइयों को उसी _GLIBCXX_USE_CXX11_ABI ध्वज के साथ संकलित किया गया है। हालांकि अगर मैं सही ढंग से समझ गया, तो यह जीसीसी 5.1 और बाद में पेश किया गया था।

  1. वहाँ जीसीसी 4.8 के साथ इस काम कर सकते हैं या हम लोगों को एक अलग _GLIBCXX_USE_CXX11_ABI साथ पुस्तकालयों पुन: संयोजित करने के लिए पूछने की आवश्यकता करने के लिए एक तरीका है?
  2. मुझे लगता है कि अगर हम जीसीसी> = 5.1 पर स्विच करने में सक्षम हैं तो हम यह काम कर सकते हैं?

धन्यवाद!

+0

इसके अलावा रेड हैट ब्लॉग पर [GCC5 और सी ++ 11 ABI] (https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/) देखें जीसीसी के मैनुअल में, [दोहरी ABI] (https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html) और [अबी :: cxx11 के साथ प्रतीकों की वजह से समस्याओं को लिंक करना?] (https: // स्टैक ओवरफ्लो पर stackoverflow.com/q/36159238/608639)। इससे हमें कई समस्याएं हुईं, खासकर जब क्लैंग जीसीसी 5/सी ++ 11 जागरूक नहीं था। यह आपके dup की तरह दिखता है, लेकिन यह कोई उत्तर नहीं दिया गया है: [? मैं जीसीसी-4.9 और जीसीसी-5 के बीच ABI असंगति संभाल चाहिए कैसे] (https://stackoverflow.com/q/37145066/608639) जोड़ने के लिए – jww

उत्तर

3

यह जीसीसी 4.8.2 के साथ सी ++ 11 ABI का उपयोग करने के लिए संभव है, लेकिन यह एक खतरनाक हैक है; आप अब तक सब पर यदि संभव हो तो अपने विक्रेताओं पूछने के लिए सी ++ 03 ABI (-D_GLIBCXX_USE_CXX11_ABI=0) या इसके बाद के संस्करण जीसीसी 5 या में नवीनीकृत करने के साथ संकलित पुस्तकालयों जहाज के लिए बेहतर होगा।

आपको जीसीसी 5 को डाउनलोड और इंस्टॉल करने की आवश्यकता होगी ताकि आप इसके libstdC++ शीर्षलेखों और पुस्तकालयों का उपयोग कर सकें, फिर सीधे जीसीसी 4.8 को प्राथमिकता में इस्तेमाल करने के लिए सीधे उपयोग करें। इसके अतिरिक्त, क्योंकि जीसीसी 4.8 में जीसीसी 5 के साथ भेजे गए libstdC++ द्वारा आवश्यक कुछ अंतर्निहितताएं गायब हैं, इसलिए आपको उनके उपयोग को हैक करना होगा।

उदाहरण के लिए, एक सरल एकल फ़ाइल अनुप्रयोग है कि शामिल संकलित करने के लिए <string>:

/usr/local/gcc-4.8.2/bin/g++ \ 
    -std=c++11 \ 
    -D_GLIBCXX_USE_CXX11_ABI=1 \ 
    -D'__is_trivially_copyable(...)=0' \ 
    -D'__is_trivially_constructible(...)=0' \ 
    -D'__is_trivially_assignable(...)=0' \ 
    -nostdinc++ \ 
    -isystem /usr/local/gcc-5.4.0/include/c++/5.4.0/ \ 
    -isystem /usr/local/gcc-5.4.0/include/c++/5.4.0/x86_64-unknown-linux-gnu \ 
    -L /usr/local/gcc-5.4.0/lib64 
    a.cpp 

यह खतरनाक है क्योंकि जीसीसी 5.4 libstdC++ जीसीसी 4.8 के साथ काम करने के लिए डिजाइन नहीं है, और intrinsics इस्तेमाल किया फिर से परिभाषित करने है (__is_trivially_copyable इत्यादि) संरचनाओं के लेआउट को बदल सकते हैं या अन्यथा आपके कार्यक्रमों और विक्रेता के पुस्तकालयों के बीच बाइनरी असंगतता का कारण बन सकते हैं।

क्रम जिसके परिणामस्वरूप निष्पादन योग्य को चलाने के लिए, आप यह भी है कि गतिशील लिंकर /etc/ld.so.conf को /usr/local/gcc-5.4.0/lib64 जोड़ने, या -Wl,-rpath /usr/local/gcc-5.4.0/lib64 का उपयोग करके उदाहरण के लिए, एक संगत libstdC++ पाता है सुनिश्चित करने के लिए की आवश्यकता होगी।

+0

अर्थपूर्ण हो सकता है '-Wl, -rpath' भी। – yugr

+0

वाह यह डरावना (और ठंडा) सामान है! बेहतर जोखिम को कम करें और सुरक्षित पथ का पालन करें और एक पुनर्मूल्यांकन के लिए पूछें। – Tanasis

संबंधित मुद्दे