2014-09-18 6 views
11

तो, मेरे पास एक प्रोग्राम है जो ओपनब्लैस के साथ चलता है और मैं इसे संकलित करना चाहता हूं। लिंकिंग प्रक्रिया इस तरह दिखती है:क्यों LD_LIBRARY_PATH बीएडी है और गतिशील पुस्तकालयों को लोड करने का सही तरीका

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include -L/opt/OpenBLAS/lib -lopenblas 

अभी तक इतना अच्छा है। अगर मैं -L विकल्प निकालने के लिए, मैं लिंक करने की प्रक्रिया

/usr/bin/ld: cannot find -lopenblas 
त्रुटियों के बिना -L सब कुछ लिंक के साथ

में कोई त्रुटि मिलती है। हालांकि, जब मैं मैं निम्नलिखित त्रुटि मिलती है इसे चलाने के लिए प्रयास करें:

./prog: error while loading shared libraries: libopenblas.so.0: cannot open shared object file: No such file or directory 

अगर मैं /opt/OpenBlas/lib को env चर LD_LIBRARY_PATH सेट मैं इस कार्यक्रम चला सकते हैं, लेकिन http://xahlee.info/UnixResource_dir/_/ldpath.html जैसे कई स्रोतों इस पर विचार एक बुरी अभ्यास के रूप में है और मैं लगभग सभी तर्क समझ सकते हैं। लेख में उल्लिखित अन्य विधि (एलडी कॉन्फ़िगरेशन को संशोधित करें) को कुछ हद तक खराब अभ्यास माना जाता है। अंत में, आप /usr/lib में लाइब्रेरी में सिमलिंक जोड़ सकते हैं। पिछले दो तरीकों से एक बड़ी समस्या यह है कि आपको सूडो पहुंच की आवश्यकता है।

तो मेरा सवाल यह है कि मैं एक साझा लाइब्रेरी से जुड़े प्रोग्राम को संकलित और चला सकता हूं जो LD_LIBRARY_PATH और सूडो एक्सेस के बिना डिफ़ॉल्ट पथ (/usr/lib) में स्थित नहीं है। लेख में वे कहते हैं कि आप साझा पुस्तकालयों को देखने के लिए बाइनरी में बस 'लिख सकते हैं' लेकिन मुझे नहीं पता कि यह कैसे करना है (-L ध्वज ऐसा नहीं कर रहा है)। मैं इस बात की सराहना करता हूं कि कोई भी इस मामले को समझा सकता है, क्योंकि मैं हर जगह देख रहा हूं और मैं बहुत उलझन में हूं (कुछ संदर्भ यह सुझाव देते हैं कि ध्वज '-एल' करना चाहिए लेकिन मैं मेरे लिए काम नहीं करता)। पहले ही, आपका बहुत धन्यवाद।

+0

आप रनटाइम लाइब्रेरी खोज पथ – sshannin

उत्तर

12

रनटाइम लाइब्रेरी खोज पथ के लिए पथ जोड़ें।

gcc -Wl,-rpath=/opt/OpenBlas/lib ... 

क्या -L विकल्प लिंक समय में करता है, -rpath विकल्प रन टाइम पर नहीं करता है।

+3

सेट करने के लिए -rpath का उपयोग कर सकते हैं यह शायद ओपी की तलाश का उत्तर है, हालांकि यह भी बुरा है क्योंकि यह निष्पादन योग्य में पथ बनाता है, जिसके लिए निष्पादन योग्य को लाइब्रेरी को स्थानांतरित करने के लिए पुन: संकलित करने की आवश्यकता होती है । तो आपको मूल रूप से सभी समाधानों को समझना चाहिए, वे सभी खराब क्यों हैं, और उसके बाद उस व्यक्ति को चुनें जो आपके उपयोग के मामले में कम से कम खराब है। ;) –

+0

@ डेविडस्वार्टज़: आप बिना किसी संकलन के लाइब्रेरी को स्थानांतरित कर सकते हैं, आपको इसे रनटाइम खोज पथ में कहीं और स्थानांतरित करना होगा ... यदि आप '-rpath' का उपयोग नहीं करते हैं तो आपके पास वही विकल्प है। और यदि आप वास्तव में पुस्तकालय को कहीं और ले जाना चाहते हैं तो आप हमेशा 'LD_LIBRARY_PATH' का उपयोग कर सकते हैं। क्षमा करें, अगर आप बाइनरी को किसी अन्य सिस्टम में कॉपी करते हैं, तो संभावना है कि '-rpath' थोड़ा * शोर * है, तो मुझे दोषों को नहीं देख रहा है। –

+0

@ डेविडस्वार्टज़: आप 'chrpath' टूल का उपयोग करके 'rpath' को पुन: संकलित किए बिना संशोधित भी कर सकते हैं।आप ओएस एक्स पर ऐसा नहीं कर सकते हैं जब तक कि नया 'rpath' छोटा न हो, लेकिन हां, कुछ भी सही नहीं है। –

5

लिनक्स पर, आवेदन के लिए निर्देशिका पथ का मतलब है और वहां से एक सापेक्ष आरपीएथ बनाने के लिए आरपीएथ में $ ओरिजिन का उपयोग करना भी संभव है। फिर आप लाइब्रेरी को बाइनरी के ज्ञात सापेक्ष पथ पर ले जाएंगे।

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include -Wl,-rpath=\$ORIGIN/lib -L/opt/OpenBLAS/lib -lopenblas 

तुम भी पुस्तकालय का पूर्ण पथ का उपयोग कर सकते हैं, और यह में लिंक कर दिया जाएगा:

gcc -o prog prog.o -O3 -I/opt/OpenBLAS/include /opt/OpenBLAS/lib/libopenblas.so 

आप निष्पादन पर "ldd" चलाते हैं, तो आप पूर्ण पथ इनकोडिंग देखना चाहिए।

+0

आपको '$ ORIGIN' उद्धृत करने की आवश्यकता होगी, या खोल इसे विस्तारित करेगा (शायद एक खाली स्ट्रिंग पर)। '' -ब्लूएल, -आरपीएथ = $ मूल/lib'' काम करेगा। –

+0

अच्छी पकड़, धन्यवाद – Juan

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