SO (शेयर्ड ऑब्जेक्ट) नंबर कैसे काम करते हैं?


123

मुझे पता है कि लिनक्स के तहत साझा की गई वस्तुएं "इतनी संख्या" का उपयोग करती हैं, अर्थात् एक साझा वस्तु के विभिन्न संस्करणों को अलग-अलग एक्सटेंशन दिए जाते हैं, उदाहरण के लिए:

  • example.so.1
  • example.so.2

मैं समझता हूं कि इस विचार की दो अलग-अलग फाइलें हैं जैसे कि एक सिस्टम पर एक लाइब्रेरी के दो संस्करण मौजूद हो सकते हैं (जैसा कि विंडोज पर "डीएलएल हेल" के विपरीत है)। मैं जानना चाहता हूं कि यह कैसे व्यवहार में काम करता है? अक्सर, मैं देखता हूं कि example.soवास्तव में एक प्रतीकात्मक लिंक है example.so.2जहां .2नवीनतम संस्करण है। फिर एक एप्लिकेशन पुराने संस्करण के आधार पर example.soइसे सही ढंग से कैसे पहचानता है? क्या कोई नियम हैं कि किस नंबर का उपयोग करना चाहिए? या यह केवल सम्मेलन है? क्या यह मामला है कि विंडोज के विपरीत, जहां सॉफ्टवेयर बायनेरिज़ को सिस्टम के बीच स्थानांतरित किया जाता है, अगर किसी सिस्टम में एक साझा ऑब्जेक्ट का एक नया संस्करण है जो स्रोत से संकलन करते समय पुराने संस्करण से स्वचालित रूप से जुड़ा हुआ है?

मुझे संदेह है कि यह संबंधित है, ldconfigलेकिन मुझे यकीन नहीं है कि कैसे।

जवाबों:


87

बायनेरिज़ स्वयं जानते हैं कि वे किस साझा लाइब्रेरी के संस्करण पर निर्भर हैं, और विशेष रूप से इसका अनुरोध करते हैं। आप lddनिर्भरता दिखाने के लिए उपयोग कर सकते हैं ; मेरे लिए lsहैं:

$ ldd /bin/ls
    linux-gate.so.1 =>  (0xb784e000)
    librt.so.1 => /lib/librt.so.1 (0xb782c000)
    libacl.so.1 => /lib/libacl.so.1 (0xb7824000)
    libc.so.6 => /lib/libc.so.6 (0xb76dc000)
    libpthread.so.0 => /lib/libpthread.so.0 (0xb76c3000)
    /lib/ld-linux.so.2 (0xb784f000)
    libattr.so.1 => /lib/libattr.so.1 (0xb76bd000)

जैसा कि आप देख सकते हैं, यह उदाहरण के लिए libpthread.so.0, केवल नहीं libpthread.so


प्रतीकात्मक लिंक का कारण लिंकर के लिए है। जब आप libpthread.soसीधे लिंक करना चाहते हैं, तो आप gccध्वज देते हैं -lpthread, और यह libउपसर्ग और .soप्रत्यय पर स्वचालित रूप से जुड़ जाता है। आप इसे .so.0प्रत्यय पर जोड़ने के लिए नहीं कह सकते हैं , इसलिए प्रतीकात्मक लिंक यह इंगित करने के लिए कि लिब के नवीनतम संस्करण को इंगित करता है


समान चिह्न "= ls" मौजूद नहीं होना चाहिए। बस "ldd ls" का उपयोग करें
bmacnaughton

1
@bmacnaughton शायद आपको एक त्रुटि देगा क्योंकि lddनिष्पादन योग्य के लिए पूर्ण पथ की आवश्यकता होती है। =lsकि zsh में, लेकिन मैं इसे बदल के बाद से हर कोई है कि खोल का उपयोग करता है करता है
माइकल Mrozek

दिलचस्प। मैं उबंटू पर बैश चला रहा हूं और यह पूर्ण पथ के बिना काम करने लगता है। स्पष्टीकरण के लिए धन्यवाद - मैं zsh का उपयोग नहीं करता।
bmacnaughton

60

साझा लाइब्रेरी में संख्याएँ लाइब्रेरी के एपीआई की पहचान करने के लिए लिनक्स में उपयोग किए जाने वाले सम्मेलन हैं। आमतौर पर प्रारूप है:

libFOO.so.MAJOR.MINOR

और जैसा कि आपने देखा कि आमतौर पर libFOO.so से libFOO.so.MAJOR.MINOR का प्रतीकात्मक लिंक है। ldconfig इस लिंक को नवीनतम संस्करण में अपडेट करने के लिए जिम्मेदार है।

जब एपीआई में बदलाव (नए प्रवेश बिंदु हटा दिए जाते हैं या पैरामीटर या प्रकार बदल जाते हैं) तो MAJOR आमतौर पर बढ़ जाता है। माइनर आमतौर पर बग फिक्स रिलीज के लिए बढ़ा दिया जाता है या जब मौजूदा एपीआई को तोड़ने के बिना नए एपीआई पेश किए जाते हैं।

एक अधिक व्यापक चर्चा यहाँ पाई जा सकती है: साझा पुस्तकालयों को भंग करना


हाय मिगुएल, उस के लिए धन्यवाद, शर्म की बात है कि मैं दो जवाब स्वीकार नहीं कर सकता क्योंकि यह उपरोक्त अच्छी तरह से पूरक है। मेरे से +1, उत्कृष्ट लिंक भी, फिर से धन्यवाद!

4
यह लगभग सही है, लेकिन यह वास्तव में है libFOO.so.MAJOR.MINOR(इसलिए अंत में नहीं)
जॉनीजेड

6
यह उत्तर बहुत गलत है । सबसे पहले, आपके द्वारा देखे जाने वाले नंबरों का API से कोई लेना देना नहीं है, ये विशुद्ध रूप से ABI हैं। दूसरा, यहाँ पर कन्वेंशन आप की तरह सुझाव देने पर अर्थ वर्जनिंग नहीं है। इसके बजाए यह एक लिंबायत सम्मेलन है जिसमें एकल लाइब्रेरी संस्करण की मैपिंग की अच्छी संपत्ति है जो ld.so की तुलना कर सकते हैं ( अधिक जानकारी के लिए gnu.org/software/libtool/manual/html_node/ देखें)
NewbiZ

23

साझा पुस्तकालयों को निम्न योजना के अनुसार संस्करणित किया जाना चाहिए:

blah.so.X.Y.Z

कहाँ पे

  • एक्स = पीछे की ओर असंगत एबीआई रिलीज
  • Y = पीछे की ओर संगत ABI रिलीज़
  • Z = आंतरिक परिवर्तन केवल - ABI में कोई परिवर्तन नहीं

आमतौर पर आप केवल पहले अंक को देखते हैं hello.so.1क्योंकि पहला अंक केवल लाइब्रेरी के "संस्करण" की पहचान करने के लिए आवश्यक है क्योंकि अन्य सभी अंक पीछे की ओर संगत हैं।

ldconfigसाझा पुस्तकालयों की एक तालिका को बनाए रखता है जो एक सिस्टम पर उपलब्ध है और जहां उस पुस्तकालय का मार्ग मौजूद है। आप इसे चलाकर सत्यापित कर सकते हैं:

ldconfig -p

जब Red Hat जैसी किसी चीज़ के लिए एक पैकेज बनाया जाता है, तो बाइनरी में बाहर बुलाई जा रही साझा लाइब्रेरी को देखा जाएगा और RPM बिल्ड समय में पैकेज की निर्भरता के रूप में जोड़ा जाएगा। इसलिए, जब आप पैकेज को स्थापित करने के लिए जाते हैं, तो इंस्टॉलर यह देखेगा कि hello.so.1सिस्टम पर जाँच करके स्थापित किया गया है या नहीं ldconfig

आप कुछ ऐसा करके पैकेज की निर्भरता देख सकते हैं:

rpm -qpR hello.rpm

यह सिस्टम (विंडोज के विपरीत) hello.soएक सिस्टम पर स्थापित होने के कई संस्करणों के लिए अनुमति देता है और एक ही समय में विभिन्न अनुप्रयोगों द्वारा उपयोग किया जाता है।


मुझे लगता है कि यह सबसे अच्छा जवाब है।
केमिन झोउ

1
साझा योजना के अनुसार साझा पुस्तकालयों का संस्करण होना चाहिए - क्या आप कृपया इस कथन के लिए संदर्भ प्रदान कर सकते हैं?
पिओट्र डोब्रोगोस्ट

19

libNAME.so कंपाइलर / लिंकर द्वारा उपयोग किया जाने वाला फ़ाइल नाम है, जब पहली बार -lNAME द्वारा निर्दिष्ट लाइब्रेरी की तलाश की जाती है। एक साझा लाइब्रेरी फ़ाइल के अंदर एक फ़ील्ड है जिसे SONAME कहा जाता है। यह फ़ील्ड तब सेट की जाती है जब लाइब्रेरी स्वयं बिल्ड प्रक्रिया द्वारा पहली बार किसी साझा ऑब्जेक्ट (इसलिए) से जुड़ी होती है। यह SONAME वास्तव में क्या है जो कि साझा किए गए ऑब्जेक्ट के आधार पर एक निष्पादन योग्य में एक लिंकर स्टोर करता है जो इसके साथ जुड़ा हुआ है। आम तौर पर SONAME का नाम libNAME.so.MAJOR के रूप में है और इसे कभी भी लाइब्रेरी से जोड़ा जाता है जो मौजूदा निष्पादकों से जुड़ा हुआ है और लाइब्रेरी के दोनों प्रमुख संस्करणों को आवश्यकतानुसार स्थापित किया जा सकता है (हालाँकि केवल एक को ही विकास के लिए इंगित किया जाएगा। libNAME.so के रूप में) इसके अलावा, लाइब्रेरी के मामूली संस्करणों के बीच आसानी से अपग्रेड करने के लिए, libNAME.so.MAJOR आम तौर पर libNAME.so.MAJOR.MINOR जैसी फ़ाइल का लिंक है। एक नया मामूली संस्करण स्थापित किया जा सकता है और एक बार पूरा हो जाने पर, पुराने लघु संस्करण के लिंक को नए माइनर संस्करण को इंगित करने के लिए टकराया जाता है, जो अपग्रेड लाइब्रेरी का उपयोग करने के लिए सभी नए निष्पादन को तुरंत अपग्रेड करता है। इसके अलावा, मेरा जवाब देखेंलिनक्स, जीएनयू जीसीसी, एलडी, संस्करण स्क्रिप्ट और ईएलएफ बाइनरी प्रारूप - यह कैसे काम करता है?

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.