2016-01-13 9 views
5

पर जीसीसी के सिस्टम संस्करण द्वारा उपयोग किए गए सी ++ एबीआई की जांच कैसे करें मेरे पास एक कॉन्फ़िगरेशन जांच है जो निर्धारित करता है कि प्लेटफ़ॉर्म और संस्करण के आधार पर g ++ को किस झंडे को पास करना है। मैं आमतौर पर सी ++ 14 सुविधाओं तक पहुंच प्राप्त करने के लिए देशी इंस्टॉल संस्करण की तुलना में जीसीसी के बाद के संस्करण का उपयोग करता हूं। पुराने प्लेटफॉर्म पर इसका मतलब है कि मुझे पुराने C++ एबीआई का उपयोग करने के लिए -D_GLIBCXX_USE_CXX11_ABI = 0 जोड़ने की आवश्यकता है या मैं C++ लाइब्रेरीज़ के होस्ट संस्करणों से लिंक नहीं कर सकता। हालांकि कुछ नए प्लेटफ़ॉर्म नए एबीआई का उपयोग करते हैं, जिसमें मामले -D_GLIBCXX_USE_CXX11_ABI = 1 (या बिल्कुल भी नहीं) आवश्यक है।लक्ष्य प्लेटफ़ॉर्म

मैं लक्ष्य प्लेटफ़ॉर्म के संस्करण (यानी lsb_release -a के आउटपुट) के आधार पर ऐसा कर सकता हूं लेकिन मुझे एक और सामान्य विधि चाहिए।

मुझे लगता है कि मैं मूल संकलक (मेरे बाद के एक के विपरीत) के साथ एक सी ++ हैलो वर्ल्ड प्रोग्राम संकलित करने के साथ आधा रास्ता हूं, लेकिन मैं एबीआई संस्करण की जांच कैसे कर सकता हूं, इस बारे में काफी जानकारी नहीं दे सकता। ईजी।

 
>strings hello | grep ABI 
.note.ABI-tag 
>strings hello | grep CXX 
GLIBCXX_3.4 

या इसी तरह हेल्लो जांच कार्यक्रम द्वारा उपयोग किए गए libstdC++ के संस्करण पर।

 
ldd ./hello | grep stdc++ | sed -e 's_.* /_/_' | cut -f 1 -d' ' |xargs strings | grep 

क्या किसी के पास कोई बेहतर सुझाव है?

अद्यतन: वास्तव में मुझे यह करने की आवश्यकता नहीं है। मेरी असली समस्या यह थी कि मेरे पास libstdC++ का पुराना संस्करण था। इसलिए आसपास लटक रहा था। संकलन ने एक संस्करण 6.0.20 उठाया और रनटाइम ने एक असंगत एक 6.0.1 9 (या संभवतः वीज़ा बनाम) उठाया। मेरे पास एक अनसुलझा प्रतीक था जिसे मैंने एबीआई संस्करण पर गलत तरीके से दोषी ठहराया था। लोकप्रिय विश्वास के विपरीत libstdC++ के मामूली संस्करण हमेशा बाइनरी संगत नहीं होते हैं। मेरा इरादा हमेशा चलने और संकलित समय पर सटीक उसी संस्करण का उपयोग करना है (यदि मेजबान देशी का उपयोग नहीं कर रहा है)।

+0

मैंने प्रश्न का उत्तर नहीं दिया लेकिन मेरी समस्या हल करने के बाद उत्तर अब मेरे लिए महत्वपूर्ण नहीं है। यह सवाल बंद किया जा सकता है। –

+1

libstdC++ आगे संगत है, मुझे यह भी यकीन नहीं है कि वे अर्थपूर्ण संस्करण के किसी भी रूप का पालन करते हैं। मैं शर्त लगाता हूं कि यदि आप 6.0.1 9 से जुड़े हैं और परिणामी कोड 6.0.20 के साथ चलाया है, तो यह ठीक काम करेगा। – rubenvb

+0

जबकि यह सच होना चाहता था। आपको अभी भी समस्याएं हो सकती हैं। मैंने पुस्तकालय के बाद के संस्करण का उपयोग करके कुछ (आंतरिक) कार्यक्रम तोड़ दिए जो कि कुछ सूक्ष्म तरीके से असंगत थे। मैं इस तरह एक सिस्टम प्रोग्राम तोड़ने का जोखिम नहीं लेना चाहता क्योंकि यह डीबग करना बहुत मुश्किल होगा। यह भी देखें http://stackoverflow.com/questions/25979778/forcing-or-preventing-use-of-a-particular-minor-version-of-libstdc –

उत्तर

0

लोकप्रिय धारणा के विपरीत libstdC++ के मामूली संस्करण हमेशा बाइनरी संगत नहीं होते हैं।

वे दोनों दिशाओं में बाइनरी संगत नहीं हैं। libstdC++। so.6.0.20 का उपयोग तब किया जा सकता है जब libstdC++। so.6.0.19 आवश्यक है, लेकिन दूसरी तरफ गोल नहीं है।

हालांकि, जीसीसी 5 से पहले सी ++ 11 समर्थन अभी भी प्रयोगात्मक था (यानी काम प्रगति पर था) और इसलिए नए सी ++ 11 घटकों के एबीआई स्थिर नहीं थे, इसलिए आप सी ++ 11 मिश्रण नहीं कर सकते/सी ++ 14 कोड जीसीसी 4.x और जीसीसी 4.y, या जीसीसी 4 और जीसीसी के साथ संकलित 4. सी ++ 98 कोड के लिए आप & मिश्रण से स्वतंत्र रूप से मिश्रण कर सकते हैं (केवल नए libstdc++.so का उपयोग करें क्योंकि यह केवल एक दिशा में संगत है)।

प्रमुख सी ++ 11 असंगतियां जीसीसी 5 से पहले का ब्यौरा https://gcc.gnu.org/wiki/Cxx11AbiCompatibility

में प्रलेखित हैं वैसे भी, अब अप्रासंगिक सवाल का जवाब देने:

मुझे लगता है कि मैं वहाँ के साथ आधे रास्ते हूँ देशी संकलक के साथ एक सी ++ नमस्ते दुनिया कार्यक्रम संकलन (के रूप में मेरे बाद में एक के खिलाफ), लेकिन मैं काफी समझ नहीं कर सकते हैं तो देशी संकलक चला सकते हैं तो मैं नहीं ABI संस्करण

जांच करने के लिए कैसे क्या देखूं समस्या यह है कि, मैक्रो का डिफ़ॉल्ट मान जांचें:

echo '#include <string>' | g++ -x c++ -E -dM - | fgrep _GLIBCXX_USE_CXX11_ABI 
+0

यह लगभग सही है लेकिन मुझे जीसीसी 4.9.3 या RHEL7 देशी 4.8 मैक्रो का उपयोग करने का उपयोग कर के लिए _GLIBCXX_ABI_TAG_CXX11 या _CXXABI_FORCED_H हो रहा है: ' > गूंज" # शामिल "| जी ++ -x सी ++-ई-डीएम - | ग्रेप ABI #define _CXXABI_FORCED_H 1 #define __GXX_ABI_VERSION 1002 #define _GLIBCXX_ABI_TAG_CXX11 __attribute ((__abi_tag__ ("cxx11"))) दूसरी तरफ ' gcc6 भी कहते हैं: ' #define _GLIBCXX_USE_DUAL_ABI 1 #define _GLIBCXX_USE_CXX11_ABI 1 ' –

+0

नहीं, वे पूरी तरह से अलग मैक्रोज़ हैं। जीसीसी 5.1.9 के साथ पेश नहीं किया गया है, न तो जीसीसी 4.9.3 और न ही 4.8 [दोहरी एबीआई] (https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html) का समर्थन करता है, इसलिए वे ** हमेशा ** ' _GLIBCXX_USE_CXX11_ABI = 0' –

+0

यदि आप आरएचईएल का उपयोग कर रहे हैं तो आपको [devtoolset] (https://access.redhat.com/documentation/en/red-hat-developer-toolset/) देखना चाहिए जो आपको एक अप-टू-अप देता है -डेट जीसीसी जो बाइनरी उत्पन्न करता है जो केवल मेजबान libstdC++ पर निर्भर करता है (और जो 'std :: string' एबीआई' के संदर्भ में सिस्टम डिफ़ॉल्ट से मेल खाता है –

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