2015-08-29 9 views
5

मैं पर OSX हूँ, distutils साथ सी में एक साझा पुस्तकालय संकलित करने के लिए कोशिश कर रहा है' setup.py (अजगर में ctypes का उपयोग कर उपयोग करने के लिए)। मैं distutils के लिए नया हूँ, लेकिन मुझे समस्याएं आ रही हैं जब साझा लाइब्रेरी मैं संकलित करना चाहता हूँ (libreboundx.so) किसी अन्य साझा लाइब्रेरी (librebound.so) पर निर्भर करता है। स्पष्ट रूप से, modify_orbits_direct.c में मैंdistutils साथ संकलन सी साझा लाइब्रेरी 'setup.py, जब पुस्तकालय एक दूसरे साझा लाइब्रेरी पर निर्भर करता है

#include "rebound.h" 

rebound.h निर्देशिका में है/उपयोगकर्ताओं/डीटी/पलटाव/src /, और rebound.h में सभी कार्यों साझा लाइब्रेरी librebound.so है, जो कर रहे हैं में/उपयोगकर्ता/डीटी/रिबाउंड /।

सीसी के साथ जोड़ने की तरह लग रहे हैं।

cc -fPIC -shared reboundx.o -L/Users/dt/rebound -lrebound -o libreboundx.so 

अद्यतन: यह स्थिति वास्तव में धारा के अंत में उदाहरण की तरह लग रहा है। 3 https://docs.python.org/2/extending/building.html पर। मैं अपने setup.py नवीनीकृत किया है नकल करने के लिए है कि एक:

libreboundxmodule = Extension('libreboundx', 
       sources = [ 'src/reboundx.c', 
          'src/modify_orbits_direct.c'], 
       include_dirs = ['src', '/Users/dt/rebound/src'], 
       extra_compile_args=['-fstrict-aliasing', '-O3','-std=c99','-march=native', '-D_GNU_SOURCE', '-fPIC'], 
       library_dirs=['/Users/dt/rebound'], 
       libraries=['rebound'], 
           ) 

यह ठीक स्थापित करता है जब मैं चलाने

pip install -e ./ 

उत्पादन बिल्ड:

You are using pip version 7.0.3, however version 7.1.2 is available. 
You should consider upgrading via the 'pip install --upgrade pip' command. 
Obtaining file:///Users/dtamayo/Documents/workspace/reboundx 
Installing collected packages: reboundx 
Running setup.py develop for reboundx 
Successfully installed reboundx-1.0 

लेकिन जब मैं

कोशिश
import reboundx 
अजगर में

, मैं एक OSError मिलती है: dlopen (lib reboundx.so, 10): प्रतीक नहीं मिला: _reb_boundary_particle_is_in_box, जो अन्य लाइब्रेरी (librebound.so) में एक फ़ंक्शन है, जिसे libreboundx.so के लिए कोड में भी नहीं कहा जाता है।

यदि मैं साझा लाइब्रेरी को ऊपर सीसी कमांड से लिंक करता हूं, तो सब कुछ काम करता है, और मैं साझा लाइब्रेरी libreboundx.so का उपयोग कर सी में पूरी तरह से ठीक कर सकता हूं। यदि मैं वही libreboundx लेने की कोशिश करता हूं। तो मैं cc कमांड के साथ संकलित करता हूं और यह छड़ी जहां setup.py डाल दिया होगा, तो अजगर में reboundx आयात करने की कोशिश, मैं बजाय

OSError: dlopen(/Users/dtamayo/Documents/workspace/reboundx/reboundx/../libreboundx.so, 10): Library not loaded: librebound.so 

मिल संदर्भित से: /Users/dtamayo/Documents/workspace/reboundx/libreboundx.so कारण: छवि

नहीं मिला यह एक rpath मुद्दा है, जहां रनटाइम पर libreboundx.so जहां एल देखने के लिए पता नहीं है की तरह हो सकता है ibrebound.so?

+1

'पुस्तकालय = [' librebound ']' संदिग्ध लग रहा है। इसमें 'lib'-prefix नहीं होना चाहिए, लेकिन केवल' रिबाउंड' होना चाहिए। आप '-लिब्राउंडबाउंड' से लिंक नहीं करते हैं, लेकिन '-रबाउंड''। इसके अलावा, क्या आप बिल्ड-आउटपुट प्रदान कर सकते हैं? – deets

+0

मैंने इसे प्रश्न में जोड़ा है। मुझे पुस्तकालयों में 'librebound' या 'rebound' के साथ सटीक वही व्यवहार/आउटपुट मिलता है (जो कुछ गलत बताता है!)। इसके अलावा, मैंने नीचे install_requires में 'rebound' जोड़ने का प्रयास किया। यह "आवश्यकता पहले से ही संतुष्ट है (अपग्रेड करने के लिए अपग्रेड करें):/उपयोगकर्ता/डेटामैयो/दस्तावेज़/वर्कस्पेस/रिबाउंड (रीबाउंडएक्स == 1.0 से) में रिबाउंड", लेकिन जब मैं पाइथन में आयात करता हूं तो वही त्रुटि देता है। – Dan

+2

ओएस एक्स पर, 'otool -D' lib के 'install_name' को दिखाता है, और' install_name_tool -id' इसे बदल देगा। यदि आप लोडिंग मॉड्यूल से संबंधित पथ चाहते हैं, तो '@ loader_path' टोकन का उपयोग करें। 'Otool -L' का उपयोग करके सूची निर्भरताओं, और 'install_name_tool -change' का उपयोग करके उन्हें बदलें। आप '-rpath' निर्भरता खोज पथ भी सेट कर सकते हैं; यह एक सापेक्ष पथ के लिए '@ loader_path' का उपयोग कर सकता है। 'एक्सटेंशन' श्रेणी में 'rpath' पैरामीटर है, लेकिन यह वर्ग वास्तव में एक सामान्य साझा मॉड्यूल (विशेष रूप से विंडोज़ पर, यदि यह मायने रखता है) बनाने के लिए उपयुक्त नहीं है। आप सीधे gcc निष्पादित करने के लिए 'ccompiler.new_compiler' को कॉल कर सकते हैं। – eryksun

उत्तर

1

सभी सुझावों के लिए धन्यवाद। मुझे इस सवाल में निर्दिष्ट होना चाहिए था कि अंत में मैं एक समाधान चाहता हूं कि मैं पीपीपी पर अपलोड करने के लिए पैकेज कर सकूं ताकि उपयोगकर्ता एक ही कमांड के साथ इंस्टॉल कर सकें। इसे ओएसएक्स और लिनक्स दोनों पर भी चलाना चाहिए, इसलिए मैंने install_name_tool को शामिल करने वाले समाधानों को प्राथमिकता दी।

मैं इसे परीक्षण करने के लिए नहीं कर पाए हैं, लेकिन मैं

runtime_library_dirs=['/Users/dt/rebound'], 

library_dirs के बगल में लिनक्स पर इस समस्या को ठीक करना चाहिए जोड़ने लगता है। जाहिर है यह मैक पर काम नहीं करता है, लेकिन आप इसके बजाय extra_link_args का उपयोग कर सकते हैं। ऊपर पोस्ट की गई libreboundxmodule परिभाषा के नीचे इसे जोड़ना,

if platform.system() == 'Darwin': 
    extra_link_args.append('-Wl,-rpath,'+'/Users/dtamayo/Documents/workspace/rebound') 

मेरी समस्या को ठीक किया गया।मुझे यहां जवाब मिला: Python runtime_library_dirs doesn't work on Mac

+1

पीपीपीआई पर अपलोड होने पर यह वास्तव में काम नहीं करेगा। जब तक उपयोगकर्ता को dtamayo कहा जाता है और दस्तावेजों के तहत कार्यक्षेत्र के भीतर से काम करता है;) आपको पुस्तकालय को अपने पैकेज के साथ बंडल करने की आवश्यकता होगी, और आपको रिश्तेदार आरपीएथ का उपयोग करने की आवश्यकता होगी, उदा। '@ execable_path' या समान उपनाम। – deets

+0

यह सही है। मैं अलग-अलग पता लगाने की कोशिश करना चाहता था कि रिबाउंड लाइब्रेरी कहाँ स्थित थी, जो संभव था क्योंकि python setup.py इंस्टॉल इसे अपने आउटपुट के हिस्से के रूप में सूचीबद्ध करता है। जब मैं पथ – Dan

+1

पथ जानता था, तब भी मैं इसे काम करने के लिए नहीं मिला था, पहले प्रयोग करने के लिए मैं क्या सुझाव दूंगा: सबसे पहले, आप जिस बंडल को चाहते हैं उसे हाथ से तैयार करें। जैसे libreboundx.dylib के अलावा librebound.dylib की प्रतिलिपि बनाएँ, और पैकेज को आज़माएं और आयात करें। यदि यह विफल हो जाता है, तो libreboundx के rpath को बदलने के लिए install_name_tool का उपयोग करें ताकि यह * पाया गया हो (स्पष्ट रूप से @ -aliases का उपयोग करके एक सापेक्ष पथ का उपयोग कर)। एक बार जब आप उस पर पहुंचे, तो अपने setup.py को मालिश करने का प्रयास करें जब तक कि यह परिणाम न बनाये/वितरित न हो जाए। – deets

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