2009-12-15 10 views
19

मुझे LD_LIBRARY_PATHलिंक समय (इस प्रश्न के पास रन टाइम के साथ कुछ लेना देना नहीं है) के साथ समस्याएं आ रही हैं।लिंक समय पर एलडी_LIBRARY_PATH और -L के बीच क्या अंतर है?

लिंक लाइन इस तरह दिखता है जब मैं बनाने के (इस छ ++ संस्करण 4.1.x का उपयोग कर एक Linux सिस्टम है) चलाएँ:

g++ a.o b.o c.o -o myapp \ 
-L/long/path/to/libs/ \ 
-L/another/long/path/ \ 
-labc -ldef -lghi 

-l विकल्पों साझा लाइब्रेरियों को संदर्भित (जैसे, libabc.so) जो मौजूद -L विकल्पों द्वारा निर्दिष्ट निर्देशिकाओं में। वे निर्देशिका LD_LIBRARY_PATH में भी दिखाई देती हैं। उस कॉन्फ़िगरेशन के साथ, लिंक सफल है, और मैं एप्लिकेशन चला सकता हूं।

/usr/bin/ld: cannot find -labc 

दूसरी ओर, अगर मैं -L विकल्पों की सूची से निर्देशिका निकालें, तब मैं कई मिलती है:

अगर मैं LD_LIBRARY_PATH से निर्देशिका निकालें, तब मैं एक ही त्रुटि पंक्ति जैसे मिल

/usr/bin/ld: warning: libabc.so, needed by /long/path/to/libs/libxyz.so, 
    not found (try using -rpath or -rpath-link) 

और उसके बाद इस तरह के रूप में कई और अधिक त्रुटियों,:

/long/path/to/libs/libdef.so: undefined reference to `Foo::Bar<Baz>::junk(Fred*)' 
जैसे चेतावनी

क्या कोई LD_LIBRARY_PATH और -L के बीच अंतर बता सकता है? मैं इस सामान को गहराई से समझना चाहता हूं, इसलिए संदर्भों की बहुत सराहना की जाती है!

इसके अलावा, LD_LIBRARY_PATH का उपयोग करने से बचने के लिए मुझे लिंक लाइन में क्या जोड़ना है?

संपादित करें: जब निर्देशिका -L से लापता थे, संकलक "-rpath या -rpath-लिंक का उपयोग करके देखें" करने का सुझाव दिया। मुझे नहीं लगता कि मैंने कभी भी उन विकल्पों को मेकफ़ाइल में देखा है। क्या तुम? यकीन नहीं है कि अगर यह LD_LIBRARY_PATH समस्या हालांकि मदद करेगा।

उत्तर

15

LD_LIBRARY_PATH की सेटिंग सर्वोच्च प्राथमिकता है, इसलिए जब यह सेट कर दिया जाता है, LD_LIBRARY_PATH ने उल्लेख किया निर्देशिकाओं का सेट भी befor पहले की खोज कर रहे हैं ई मानक सेट
निर्देशिकाओं के। तो LD_LIBRARY_PATH की स्थिति में
-l विकल्प के साथ वर्णित पुस्तकालयों को देखने पर प्रभाव डाल रहा है। LD_LIBRARY_PATH के बिना कुछ निर्भरताओं
निर्देशिकाओं के मानक सेट से हल हो गए हैं।

हालांकि डिबगिंग के साथ और
एक पुस्तकालय सामान्य विकास के वातावरण सेटअप और तैनाती में इसके उपयोग बुरा माना जाता है के एक नए संस्करण आज़माने के लिए LD_LIBRARY_PATH मदद की स्थापना।

भी साझा पुस्तकालय

+4

यह बताते हुए कि कुछ क्यों "बुरा" कह रहा है, यह निश्चित रूप से एक "बुरी" चीज है (और मैं कह सकता हूं कि यह क्यों है)। – cedbeu

7

LD_LIBRARY_PATH एप्लिकेशन चलाने पर साझा पुस्तकालयों को ढूंढने का इरादा है। यह एक दुष्प्रभाव है कि यह आपके लिंक को प्रभावित कर रहा है, और आपको उस पर भरोसा नहीं करना चाहिए।

एक बार अवांछित पक्ष प्रभाव के रूप में, LD_LIBRARY_PATH भी लिंक पर खोज की जाएगी (LD) निर्देशिका एल (भी अगर कोई -एल झंडा दिया जाता है) के साथ निर्दिष्ट के बाद मंच।

Why LD_LIBRARY_PATH is bad

+0

मैं मानता हूँ यह एक पक्ष प्रभाव है, और मैं उस पर भरोसा करने के लिए नहीं पसंद करेंगे। लेकिन मुझे यकीन नहीं है कि LD_LIBRARY_PATH में निर्देशिकाओं को कहां रखा जाए - क्योंकि उन्हें केवल -L में पर्याप्त रूप से पर्याप्त नहीं है। लिंक के लिए धन्यवाद - अच्छी पढ़ाई! – Dan

+0

साइड इफेक्ट क्या है जो LD_LIBRARY_PATH को खराब करने का कारण बनता है और हमें /etc/ld.so.conf में पथ जोड़ना चाहता है ???? –

2

तो मुझे लगता है कि के लिए गए थे, मैं कहूँगा कि लिंकर पुस्तकालयों कि आपके सीधे संपर्क (जैसे, libabc.so, libdef.so, और libghi.so) गतिशील रूप से जुड़े हुए हैं के खिलाफ हल करने LD_LIBRARY_PATH उपयोग करने पर वापस गिर रही है । ld के लिए मैन्युअल पृष्ठ को देखते हुए, यह .so के विरुद्ध लिंक करने जैसा लगता है जो -rpath का उपयोग करके बनाया गया था, यह प्रभावित करेगा कि गतिशील रूप से बाध्य प्रतीकों का लुक कैसे काम करता है।

28

इस प्रश्न के दो जवाब हैं, उत्तर का हिस्सा संकलन-समय लिंकिंग में है (iee gcc -lfoo -L/usr/lib ... जो बदले में ld पर कॉल करता है), और रन-टाइम लिंकर लुकअप।

जब आप अपने प्रोग्राम को संकलित करते हैं, तो कंपाइलर सिंटैक्स जांचता है, और फिर लिंकर यह सुनिश्चित करता है कि अन्य चीजों के साथ निष्पादन के लिए आवश्यक प्रतीक मौजूद हैं (यानी चर/विधियां/आदि)। LD_LIBRARY_PATH, जैसा कि नोट किया गया है, gcc/ld व्यवहार के साथ-साथ रन-टाइम लिंकर जिस तरह से खोज पथ को संशोधित करके व्यवहार करता है, को बदलने का दुष्प्रभाव होता है।

जब आप अपना प्रोग्राम चलाते हैं, तो रन-टाइम लिंकर वास्तव में साझा लाइब्रेरी (डिस्क पर या मेमोरी से संभव होने पर) प्राप्त करता है, और साझा प्रतीकों/कोड/आदि में लोड करता है। LD_LIBRARY_PATH इस खोज पथ को निहित रूप से प्रभावित करता है (कभी कभी नहीं एक अच्छी बात है, के रूप में उल्लेख किया गया है।)

इस के लिए सही फिक्स का उपयोग कर LD_LIBRARY_PATH सबसे Linux सिस्टम पर रास्ता है कि /etc/ld.so.conf करने के लिए अपने साझा लाइब्रेरी शामिल हैं जोड़ने के लिए है बिना (या कुछ वितरण में, में एक फ़ाइल बनाने के /etc/ld.so.conf.d/ इसमें पथ के साथ) और रनटाइम लिंकर बाइंडिंग कैश को अद्यतन करने के लिए ldconfig (/sbin/ldconfig रूट के रूप में) चलाएं। डेबियन पर

उदाहरण:

[email protected]:~$ cat /etc/ld.so.conf.d/usrlocal.conf 
/usr/local/lib 

फिर जब कार्यक्रम क्रियान्वित किया जाता है, रन-टाइम लिंकर उन निर्देशिकाओं में पुस्तकालयों कि आपके द्विआधारी के खिलाफ जोड़ा गया है के लिए दिखेगा।

आप क्या रन-टाइम लिंकर के बारे में जानता पुस्तकालयों में जानना चाहते हैं, तो आप उपयोग कर सकते हैं:

[email protected]:~$ ldconfig -v 

/usr/lib: 
libbfd-2.18.0.20080103.so -> libbfd-2.18.0.20080103.so 
libkdb5.so.4 -> libkdb5.so.4.0 
libXext.so.6 -> libXext.so.6.4.0 

और, यदि आप को पता है कि एक द्विआधारी पुस्तकालयों के खिलाफ जुड़े है चाहते हैं, आप की तरह उपयोग कर सकते हैं ldd इस तरह है, जो आपको बता देंगे जो पुस्तकालय अपने क्रम लिंकर चयन करने के लिए जा रहा है:

[email protected]:~$ ldd /bin/ls 
linux-vdso.so.1 => (0x00007fffda1ff000) 
librt.so.1 => /lib/librt.so.1 (0x00007f5d2149b000) 
libselinux.so.1 => /lib/libselinux.so.1 (0x00007f5d2127f000) 
libacl.so.1 => /lib/libacl.so.1 (0x00007f5d21077000) 
libc.so.6 => /lib/libc.so.6 (0x00007f5d20d23000) 
+0

+1, लिंकिंग और लोडिंग कार्यों के बारे में अच्छी संक्षिप्त वर्णन। ld.so.conf ऐसा लगता है कि इसमें LD_LIBRARY_PATH जैसी कुछ समस्याएं हो सकती हैं, हालांकि यह लिंक-टाइम को प्रभावित नहीं करेगी, केवल रन-टाइम - इसका उल्लेख यहां चीजों को बेहतर बनाने के लिए आधे से प्रयास किए गए प्रयास। – Dan

+0

हालांकि, मुझे अभी भी समझ में नहीं आ रहा है कि क्यों LD_LIBRARY_PATH की अनुपस्थिति लिंक को रोकती है। संपादन ld.so.conf एक विकल्प नहीं है। यदि यह था, तो क्या मैं लिंक-टाइम पर होने वाली समस्या का समाधान भी करूंगा जब मैं LD_LIBRARY_PATH से निर्देशिका हटा देता हूं? – Dan

+0

जिस तरह से मैंने आपकी मूल पोस्ट पढ़ी है वह निम्नलिखित है: -L/path/to/lib1 -L/path/to/lib2and3 -llib1 -llib2 -llib3 के साथ संकलन, लेकिन निष्पादन विफल रहता है जब तक कि LD_LIBRARY_PATH के पास/पथ// lib {1,2and3} इसमें। यदि संकलन समय पर लिंकिंग विफल हो रही है, तो आपके -L पथों से कुछ ख़राब है ... क्या आप वास्तविक संकलन आदेश पोस्ट कर सकते हैं जो विफल रहता है? –

1

जी के लिए आदमी की जाँच हो रही ++ के बारे में अधिक जानकारी के लिए लिनक्स प्रलेखन से this HOWTO उल्लेख, मुझे पता चला तो समय को जोड़ने पर कि -lxxxxx विकल्प प्रदान पथ -L में libxxxxx.a की तलाश में है, केवल .a फ़ाइल होगा लोड किया जाना चाहिए। रन टाइम पर, यदि कोई लाइब्रेरी गुम हो जाती है तो केवल लाइब्रेरी को साझा ऑब्जेक्ट के रूप में। इसलिए लोड किया जाएगा और फिर यह LD_LIBRARY_PATH में दिखेगा। निष्पादन योग्य पर मैं काम कर रहा हूं, मुझे लगता है कि कुछ लाइब्रेरी निर्देशिका में, संस्करण libxxxx.a और libxxxx.so है इसलिए मुझे लगता है कि इसका अर्थ यह है कि लाइब्रेरी को लिंकिंग समय पर जोड़ा जा सकता है या किसी साझा ऑब्जेक्ट के रूप में रन टाइम पर लिंक किया जा सकता है।

यदि कोई लाइब्रेरी केवल साझा ऑब्जेक्ट के रूप में मौजूद है, तो इसका मतलब है कि लाइब्रेरी निर्देशिका पथ को रन समय पर LD_LIBRARY_PATH होना चाहिए। यदि कोई लाइब्रेरी केवल एक .aa के रूप में मौजूद है, तो इसका मतलब है कि इसे निष्पादन योग्य के निर्माण पर जोड़ा जाना चाहिए और फिर-निर्देशिका निर्देशिका और -lxxxxx को संकलन समय पर g ++ पर प्रदान करने की आवश्यकता है।

यह मेरी समझ है .... और कम से कम यह अपनी टिप्पणियों के साथ कतार में है

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