16

के साथ साझा लाइब्रेरी निर्भरता मैं distutils के लिए एक नौसिखिया हूँ और मुझे एक समस्या है जो वास्तव में मुझे अटक गया है। मैं एक पैकेज है जिसमें एक्सटेंशन की आवश्यकता है संकलन कर रहा हूँ, इसलिए मैं विस्तार इस प्रकार है:distutils

a_module = Extension(
      "amodule", 
      ["initmodule.cpp"], 
      library_dirs=libdirs, 
      extra_objects = [ 
        "unix/x86_64/lib/liba.so" 
        "unix/x86_64/lib/lib.so", 
        "unix/x86_64/lib/libc.so"], 
    ) 

मैं तो सेटअप विधि चलाएँ:

setup(name="apackage", version="7.2", 
     package_dir = {'':instdir+'/a/b/python'}, 
     packages=['apackage','package.tests'], 
     ext_modules=[hoc_module] 
) 

पैकेज वितरण ठीक से किया जाता है और मैं यह कर सकते हैं "अजगर सेटअप "स्थापित .py ठीक लेकिन जब मैं कोशिश करते हैं और अपने पैकेज आयात मैं एक त्रुटि ImportError: liba.so.0: cannot open shared object file: No such file or directory

मुझे लगता है कि जब मैं अपने LD_LIBRARY_PATH को liba.so.0 के स्थान जोड़ने के कार्यक्रम ठीक चलाना चाहते हैं। दुर्भाग्य से मैंने इन मॉड्यूल को नहीं लिखा है और संकलन की अच्छी समझ नहीं है। मैं इसका आनंद लेने के लिए कई दिनों तक इसे समझने की कोशिश कर रहा हूं।

अद्यतन: मैं extra_objects को liba.a गुजर, libb.a आदि फ़ाइलों की कोशिश की लेकिन यह काम नहीं किया है, तो निम्न errror पैदा: liba.a: प्रतीक नहीं पढ़ सकता है: गलत मान collect2: ld 1 निकास की स्थिति लौटा दी। जो मैं करने की कोशिश कर रहा हूं वह एक पायथन मॉड्यूल पैकेज है जिसके लिए लाइब्रेरी को संकलित करने की आवश्यकता होती है जो स्वयं अन्य पुस्तकालयों पर निर्भर करता है जिन्हें मुझे पैकेज में शामिल करने की आवश्यकता होती है। मुझे संदेह है कि मेरी समस्या इस के समान ही है: http://mail.python.org/pipermail/distutils-sig/2009-February/010960.html लेकिन वह एक हल नहीं किया गया था, मैंने सोचा था कि शायद दो साल पुराना एक प्रस्ताव मिला है?

अद्यतन 2: अभी के लिए मैं कर रहा द्वारा इस समाधान कर लिया है:

 data_files=[('/usr/local/lib', glob.glob('unix/x86_64/lib/*'))] 

कहना है कि, मैं पुस्तकालयों मैं/usr/स्थानीय/lib में कोई इच्छित सामग्री कॉपी कर रहा हूँ। हालांकि, मैं इस समाधान के साथ बेहद खुश नहीं हूं, क्योंकि कम से कम मेरे उपयोगकर्ताओं को रूट विशेषाधिकार रखने की आवश्यकता नहीं है और यह भी क्योंकि यह अभी भी Redhat distros काम नहीं कर सकता है। तो अगर कोई इस फिक्स से बेहतर कुछ सुझाव दे सकता है तो कृपया मुझे बताएं।

उत्तर

14

आप संकलक या लिंकर को झंडे पास कर सकते हैं ताकि यह पता चल सके कि LD_LIBRARY_PATH को ठीक से सेट करने की आवश्यकता को कम करने के लिए रनटाइम पर पुस्तकालयों को कहां ढूंढना है। विवरण के रास्ते में

# Will link just fine, then fail to find libpcap.so unless it's in LD_LIBRARY_PATH 
gcc -o blah blah.o -lpcap -L/opt/csw/lib 

# If libpcap is in LD_LIBRARY_PATH, it'll link fine. Other people who may not have 
# LD_LIBRARY_PATH set properly can still run it without fixing their environment 
gcc -o blah blah.o -lpcap -R/opt/csw/lib 

# This will allow me to link and execute the binary without having LD_LIBRARY_PATH 
# setup properly 
gcc -o blah blah.o -lpcap -{L,R}/opt/csw/lib 

# This makes it possible to use relative paths. The literal string `$ORIGIN/../lib/` 
# gets stored in the binary (`readelf -d binary_name` if you want to see the effect 
# it has), which causes `$ORIGIN` to resolve to the directory containing the binary 
# when it was executed. In a makefile, you'll see that written as `$$ORIGIN/../lib/` 
# to prevent `make` from expanding it. 
gcc -o blah blah.o -lsomelib -L/whatever/path/floats/your/boat -R'$ORIGIN/../lib/' 

, मामले में यह स्पष्ट नहीं था (के बाद से मैं एक स्पष्टीकरण के बिना जवाब नफरत):: मैं कुछ उदाहरणों के साथ वर्णन करेंगे

  • रास्तों -L साथ दिया जाता है केवल जब तुम
  • रास्तों -R साथ दिया लिंक कर रहे हैं केवल पुस्तकालयों को खोजने के लिए उपयोग किया जाता है जब बाइनरी के निष्पादित किया जाता है
+0

शानदार उत्तर, इस http: // sebsauvage के साथ आपके उत्तर को जोड़कर। नेट/पायथन/mingw.html मैं आवश्यक मॉड्यूल को आवश्यक तरीके से बनाने में सक्षम था। बहुत बहुत धन्यवाद। –

+0

कोई समस्या नहीं, मुझे खुशी है कि मैं –

+3

FYI की सहायता कर सकता हूं: '-R' $ ORIGIN /../ lib/''विकल्प जोड़ने के बजाय, आप' runtime_library_dirs =" $ ORIGIN /../ lib/"आपकी 'विस्तार' परिभाषा के लिए (यह अभ्यास में एक ही चीज़ है)। –

7

Extension वर्ग के लिए extra_objects तर्क इतना लाइब्रेरी को अपने विस्तार के भीतर लिंक करने की एक सूची है, लेकिन उस लिंकर के लिए पारित किया जाएगा (और फ़ाइल नाम एक्सटेंशन शामिल नहीं होना चाहिए, distutils के बाद वस्तु फ़ाइलों की एक सूची नहीं है उनको जोड़ देगा।) ऐसा नहीं करता जो आप चाहते हैं।

यदि आप विशिष्ट साझा पुस्तकालयों के खिलाफ लिंक करना चाहते हैं, तो उन फ़ाइलों के नाम आपको सुझाव देते हैं कि आपको दो चीजें करना है: संकलित को उन साझा पुस्तकालयों के खिलाफ लिंक करने के लिए कहें, और गतिशील लिंकर को बताएं (आम तौर पर ld.so) उन साझा पुस्तकालयों को कहां खोजें। librariesExtension पर तर्क का उपयोग करके पुस्तकालयों के खिलाफ लिंक करने के लिए संकलक को बता सकते हैं, जो लाइब्रेरी नामों की सूची होनी चाहिए (lib उपसर्ग और .so प्रत्यय के बिना।) आपके उदाहरण में ['a', 'b', 'c'] (हालांकि यह लग रहा है 'b' की तरह ''lib.so की गिर गया, और 'c' वास्तव में प्रणाली libc के साथ संघर्ष होगा।)

जहां इन साझा पुस्तकालयों, LD_LIBRARY_PATH वातावरण चर सेट करके किया जा सकता है के रूप में तुमने किया था, या द्वारा खोजने के लिए लिंकर बोलने सिस्टम-व्यापी कॉन्फ़िगरेशन सेटिंग बदलना (ldconfig के साथ या /etc/ld.so.conf संपादित करके), या एक्सटेंशन मॉड्यूल में खोज पथ को हार्डकोड करके; आप runtime_library_dirs को Extension पर तर्क देकर उत्तराधिकारी कर सकते हैं।पथ को हार्डकोड करने के अपने स्वयं के मुद्दे हैं, हालांकि - आपको उन पुस्तकालयों को एक ही स्थान पर रखना होगा, और एक्सटेंशन मॉड्यूल के सभी उपयोगकर्ताओं के लिए सुलभ होना होगा।

(वैकल्पिक रूप से, आप केवल स्थिर रूप में पुस्तकालयों प्रदान करके गतिशील जोड़ने के बजाय आंकड़े उपयोग कर सकते हैं, उदाहरण के लिए, liba.a अभिलेखागार (जिसमें मामले distutils उन्हें स्वचालित रूप से करने के लिए स्थिर लिंक करेगा।) वह मूल रूप से इसका मतलब है पूरे पुस्तकालय शामिल किया गया है एक्सटेंशन मॉड्यूल में, जिसमें विभिन्न डाउनसाइड्स और अपसाइड हैं।)

+0

तुम इतने धन्यवाद पुस्तकालयों को खोजने के लिए इस्तेमाल किया आपके विस्तृत और उत्कृष्ट उत्तर के लिए बहुत कुछ। क्या मैं समझने में सही हूं कि runtime_library_dirs को एक सापेक्ष पथ के रूप में सेट किया जाना चाहिए, अन्यथा मुझे नहीं लगता कि इसे हार्डकोड किया जा सकता है? साथ ही, क्या मुझे पुस्तकालयों या extra_objects कीवर्ड में स्थिर रूप से जुड़े पुस्तकालयों (यानी liba.a अभिलेखागार) पास करना चाहिए। दुर्भाग्य से दस्तावेज इन दो सवालों पर मुझे बहुत मदद नहीं कर रहा है। –

+1

एक सापेक्ष निर्देशिका को runtime_library_dirs के रूप में पास किया जा सकता है, लेकिन यह एक अच्छा विचार नहीं है (क्योंकि एक्सटेंशन मॉड्यूल निर्माण प्रक्रिया के दौरान चारों ओर घूमता है, और उसी पथ को सभी के लिए काम करना होगा।) स्थिर रूप से जोड़ने के लिए, आप पास करने का प्रयास कर सकते हैं '.a' अभिलेखागार 'extra_objects' तर्क के रूप में, हालांकि यह नहीं है कि' extra_objects' क्या है और मुझे यकीन नहीं है कि यह काम करेगा या नहीं। शायद आपको उस चीज़ पर विस्तार करना चाहिए जो आप वास्तव में करना चाहते हैं। –

+0

आपके उत्तर के लिए धन्यवाद, मैंने अपने मूल प्रश्न में कुछ और विवरण जोड़ा है। –

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