2011-01-13 13 views
7

मान लीजिए मैं:जीसीसी एक साझा वस्तु की लिंकर नाम को जोड़ने

  • मशीन एक पर /usr/lib/libsomething.so.1;
  • /usr/lib/libsomething.so.2 मशीन बी

पर दोनों मशीनों उनके संबंधित libs को /usr/lib/libsomething.so symlinking है।

libsomething.so.1 => /usr/lib/libsomething.so.1 

इसका मतलब यह है कि यह पुस्तकालय को खोजने के लिए सक्षम नहीं होगा:

मशीन एक पर

अगर मैं -lsomething (या यहां तक ​​/usr/lib/libsomething.so) के साथ gcc का उपयोग कर लिंक यह सिमलिंक का पालन करेंगे, और ldd की तरह कुछ का उत्पादन मशीन बी

अब मुझे पता है कि ये प्रमुख संस्करण संख्या में परिवर्तन हैं और मुझे पता है कि वे संगत नहीं हो सकते हैं, लेकिन मैं उस जोखिम को लेने के लिए तैयार हूं। क्या मैं लिंकर बताना चाहूँगा libsomething.so देखने के लिए, और सिमलिंक का पालन नहीं करते तो ldd

libsomething.so => /usr/lib/libsomething.so.1 
एक पर

लेकिन

libsomething.so => /usr/lib/libsomething.so.2 
बी पर

और फिर लोडर दिखाएगा सिमलिंक का पालन करेगा जो भी संस्करण है।

इसके अलावा, मैं डलोपेन या कुछ भी लोड करने में देरी नहीं करना चाहता हूं। मैं इसे संकलित समय पर साझा ऑब्जेक्ट से लिंक करना चाहता हूं।

क्या यह भी संभव है?

उत्तर

8

निष्पादन योग्य बनाना जो साझा लाइब्रेरी के किसी भी उपलब्ध संस्करण का उपयोग करता है, ज़ाहिर है, संभव है।

समस्या यह है कि आप संस्करण-विशिष्ट soname (libsomething.so.1 और libsomething.so.2) करने के लिए अपने निष्पादन जुड़ा हुआ था। आपको इसे बदले हुए soname libsomething.so के साथ किया जाना चाहिए था।

इसे प्राप्त करने के लिए, बिल्ड मशीन पर आपको libsomething.so (संस्करण के बिना) के साथ लाइब्रेरी को संकलित और स्थापित करना चाहिए ताकि लिंकर निष्पादन योग्य होने पर इस सोनम को चुन सके।

Shared Libraries HOWTO के अनुसार, आप आवश्यक पारित कर सकते हैं unversioned soname लाइब्रेरी बनाना, जबकि: फिर

gcc -shared -Wl,-soname,libsomething.so -o libsomething.so.X objectsomething.o 

, जैसे ही आप पुस्तकालय स्थापित करने और चलाने के ldconfig के रूप में, आपके पास:

  • symlink /lib/libsomething.so मशीन ए पर /lib/libsomething.so.1 पर इशारा करते हुए;
  • सिमलिंक मशीन बी पर /lib/libsomething.so.2 को /lib/libsomething.so इशारा

लोडर (चलाने ldd) परवाह किए बिना जहां यह की ओर इशारा करता unversioned सिमलिंक का चयन करेंगे:

  • मशीन एक पर libsomething.so => /lib/libsomething.so (0xNNNNNNNN);
  • मशीन बी पर libsomething.so => /lib/libsomething.so (0xNNNNNNNN)

लिनक्स गतिशील लोडर (ld.so) निष्पादन योग्य (ELF NEEDED) में लिखा उनके soname मूल्य के आधार पर पुस्तकालयों हल करता है। एक्जिक्यूटिव बनाने के दौरान मूल्य लाइब्रेरी फ़ाइल (ईएलएफ SONAME) से कॉपी किया गया है। जब तक निष्पादन योग्य में दर्ज सोनम से मेल खाने वाली लक्ष्य प्रणाली पर एक सिम्लिंक होता है, तब तक इस सिम्लिंक द्वारा इंगित लाइब्रेरी लोड की जाएगी।


के अपने सेटअप और इस शो के माध्यम से चलाते हैं मान्यताओं verifing के लिए आदेश।

मैंने स्पष्टता के लिए परीक्षण और समायोजित आउटपुट i686 पर फेडोरा 18 X86_64 का उपयोग किया।

  • libsomething.so.1 और libsomething.so.2 दोनों संकलित करें। सुनिश्चित करें कि SONAMElibsomething.so unversioned पर सेट है:

    readelf -a libsomething.so.1 | grep SONAME 
    0xNNNNNNNN (SONAME)    Library soname: [libsomething.so] 
    
    readelf -a libsomething.so.2 | grep SONAME 
    0xNNNNNNNN (SONAME)    Library soname: [libsomething.so] 
    
  • /lib/ निर्देशिका के अंतर्गत उनके संबंधित मशीनों में पुस्तकालयों को स्थापित करें। दोनों मशीनों पर ldconfig -v चलाएं और आउटपुट सत्यापित करें।

    ldconfig -v 2>&1 | grep something 
    libsomething.so -> libsomething.so.1 (changed) 
    
    ldconfig -v 2>&1 | grep something 
    libsomething.so -> libsomething.so.2 (changed) 
    
  • संकलित निष्पादन योग्य और यकीन है कि यह NEEDED में संस्करण के बिना एक ही soname को संदर्भित करता है बनाते हैं।

    readelf -a executable | grep NEEDED 
    0xNNNNNNNN (NEEDED)    Shared library: [libsomething.so] 
    
  • आप निष्पादन योग्य अब unversioned libsomething.so पर निर्भर करता है। दोनों मशीनों के लिए निष्पादन योग्य कॉपी करें और दोनों प्रतियों के विरुद्ध ldd चलाएं।

    ldd executable 
    libsomething.so => /lib/libsomething.so (0xNNNNNNNN) 
    

    अंतिम आउटपुट दोनों मशीनों पर समान है क्योंकि निष्पादन योग्य संस्करण के बिना सोनम के साथ बनाया गया था। यह लोडर मशीनों पर लोडर को अपरिवर्तित सिम्लिंक लेता है। और मशीन के आधार पर, सिम्लिंक लाइब्रेरी libsomething.so.1 या libsomething.so.2 के विभिन्न कार्यान्वयन को इंगित कर सकता है।

+0

मैं पुस्तकालय का निर्माण नहीं कर रहा था, मुझे लगता है कि असली जवाब सिर्फ मैंने जो सुझाव दिया है, वह नहीं करना है, और यदि आप वास्तव में धोखा देना चाहते हैं, तो सिम्लिंक का उपयोग करें। इसने कुछ अच्छी जानकारी प्रदान की हालांकि मैं स्वीकार कर रहा हूं। –

2

यह मशीन बी पर पुस्तकालय

को खोजने के लिए सक्षम नहीं होगा इसका मतलब यह है और यह करने के लिए वैसे भी माना जाता नहीं है।

soversions की बहुत परिभाषा से, libsomething.so.2 इंगित करता है कि एपीआई/एबीआई libsomething.so.1 के लिए असंगत है। इसलिए, लोड होने के लिए पुस्तकालयों की प्रोग्राम की तालिका में libsomething.so जोड़ना वास्तव में गलत होगा। libsomething.so सिम्लिंक केवल डीडी के संकेत के रूप में कार्य करता है क्योंकि डिफ़ॉल्ट रूप से चुनने के लिए कौन सा विचलन होता है।

जो भी फ़ाइल एलडी वास्तव में खोलने के समाप्त हो गया है, यह प्रोग्राम में एन्कोड करने के लिए डीटीएनएन/सोनम फ़ील्ड ले जाएगा। यदि आप इसे नहीं चाहते हैं, तो बेटे के साथ libsomething सुसज्जित नहीं है। लेकिन यह आसानी से दर्द हो सकता है ... प्रोग्राम चलाने की कोशिश करते समय अनुपलब्ध प्रतीकों में भागने से शुरू होता है।

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