2012-06-13 12 views
33

वितरित करना मैं बड़ी सी ++ साझा लाइब्रेरी (libbig.so) से कुछ फ़ंक्शन लेने की कोशिश कर रहा हूं और उन्हें साइथन के माध्यम से पायथन पर बेनकाब कर रहा हूं। ऐसा करने के लिए, मुझे थोड़ा सी ++ फ़ाइल (small.cpp) मिल गया है जो साझा लाइब्रेरी की कार्यक्षमता के चारों ओर एक पतली रैपर प्रदान करता है, जिस तरह से मुझे साइथन (pysmall.pyx) के माध्यम से कॉल करना आसान हो जाता है।एक साझा लाइब्रेरी और कुछ सी कोड को एक सिंथॉन एक्सटेंशन मॉड्यूल

libbig.so -> small.cpp, small.h -> libsmall.so -> pysmall.pyx -> pysmall.cpp -> pysmall.so

मैं का निर्माण और यह एक्सटेंशन मॉड्यूल चला सकते हैं मेरी अपने कंप्यूटर: मैं libsmall.so में छोटा.cpp संकलित करता हूं, और फिर एक्सटेंशन मॉड्यूल pysmall.so बनाने के लिए setup.py में एक्सटेंशन ऑब्जेक्ट में "पुस्तकालय = ['छोटा']" कहता हूं।

अब मैं इस एक्सटेंशन मॉड्यूल को वितरित करने की कोशिश कर रहा हूं, और मुझे संसाधनों को ट्रैक करने में कठिनाई हो रही है जो एक सिंथॉन मॉड्यूल के साथ-साथ सी स्रोत और साझा पुस्तकालयों को वितरित करने के लिए setup.py सर्वोत्तम प्रथाओं का वर्णन करते हैं। मैंने "Installing Python Modules", "Distributing Python Modules", और "Distributing Cython Modules" के माध्यम से पढ़ा है। मैं समझता हूं कि एक्सटेंशन मॉड्यूल को अपने आप कैसे वितरित करना है। मैं विस्तार मॉड्यूल की निर्भरताओं को वितरित करने के सर्वोत्तम तरीके के बारे में कम निश्चित हूं।

साइथन दस्तावेज इंगित करता है कि आपको जेनरेटेड। सीपीपी फाइलों के साथ-साथ .pyx फ़ाइलों को शामिल करना चाहिए, यदि साइथन मौजूद नहीं है, फिर भी यह प्रत्येक स्थिति को सर्वोत्तम तरीके से संभालने का तरीका दिखाने के लिए कोड प्रदान नहीं करता है। यह भी उल्लेख नहीं करता है कि साझा पुस्तकालयों को वितरित करने के लिए जिस पर साइथन मॉड्यूल निर्भर करता है।

मैं pandas, lxml, pyzmq, h5py, और अधिक से setup.py स्क्रिप्ट्स के माध्यम से खुदाई कर रहा हूं, और वहां बहुत कुछ काम हो रहा है। अगर किसी के पास पॉइंटर्स या उदाहरण कोड है जो इस प्रक्रिया को तेज कर सकता है, तो मैं निश्चित रूप से इसकी सराहना करता हूं!

उत्तर

16

1) libbig.so

यह वितरित किया जा रहा एक समस्या यह है कि अजगर के साथ मदद करने के लिए नहीं जा रहा है है। आप किसके लक्ष्यीकरण कर रहे हैं? यदि यह लिनक्स है, तो क्या आप अनुरोध कर सकते हैं कि वे इसे अपने पैकेज मैनेजर के साथ इंस्टॉल करें? यदि libbig को पैकेज प्रबंधक के माध्यम से वितरित नहीं किया गया है या यह लिनक्स नहीं है और आप एकाधिक आर्किटेक्चर को लक्षित कर रहे हैं, तो आपको libbig स्रोत वितरित करना पड़ सकता है।

2) साइथन/सेटअपटोल।

सचमुच, मुझे लगता है कि लोगों को साइथन के लिए बस इतना आसान लगता है। इस तरह कोड के केवल एक ग्राउंड सच्चे संस्करण हैं, और आपको .pyx और .cpp कोड के बीच असंगतताओं के बारे में चिंता करने की आवश्यकता नहीं है। ऐसा करने का सबसे आसान तरीका distutils के बजाय setuptools का उपयोग करना है। इस तरह, आप उपयोग कर सकते हैं:

setup('mypackage', 
    ... 
    install_requires=['cython']) 

कुल में, अपने setup.py स्क्रिप्ट की तरह कुछ दिखेगा:

# setup.py 

from setuptools import setup, Extension 
from Cython.Distutils import build_ext 

pysmall = Extension('pysmall', 
    sources = ['pysmall.pyx', 'small.cpp'], 
    include_dirs = ['include/']) 

setup(name='mypackage', 
     packages=['yourpurepythonpackage'], 
     install_requires=['cython==0.17'], 
     ext_modules=[pysmall], 
     cmdclass = {'build_ext': build_ext}) 

आप cython की आवश्यकता होती है, आप की तरह कुछ कर सकते हैं करने के विचार पसंद नहीं है:

# setup.py 

import warnings 
try: 
    from Cython.Distutils import build_ext 
    from setuptools import setup, Extension 
    HAVE_CYTHON = True 
except ImportError as e: 
    HAVE_CYTHON = False 
    warnings.warn(e.message) 
    from distutils.core import setup, Extension 
    from distutils.command import build_ext 

pysmall = Extension('pysmall', 
    sources = ['pysmall.pyx', 'small.cpp'], 
    include_dirs = ['include/']) 

configuration = {'name': 'mypackage', 
     'packages': ['yourpurepythonpackage'], 
     'install_requires': ['cython==0.17'], 
     'ext_modules': [pysmall], 
     'cmdclass': {'build_ext': build_ext}} 

if not HAVE_CYTHON: 
    pysmall.sources[0] = 'pysmall.cpp' 
    configuration.pop('install_requires') 

setup(**configuration) 
+2

कृपया ध्यान दें कि नए 'setuptools' और' distutils' संस्करणों में) (मैं 'setuptools' 5.7 का उपयोग कर रहा हूं), आदेश उनके मॉड्यूल में स्थानांतरित हो गए थे। तो आप क्रमशः setuptools.command.build_ext आयात build_ext' या 'distutils' से 'करना चाहते हैं। – Midnighter

+1

आपका पहला सेटअप.py यह है कि यह Cython.Distutils आयात करता है इससे पहले कि यह मौजूद नहीं है, इसे स्थापित करने का मौका है। – zneak

+0

एक और विकल्प एक कोंडा पैकेज बनाना होगा, जिसे 'libbig.so' बंडल किया जा सकता है। https://conda.io/docs/user-guide/tutorials/build-postgis.html – oLas

7

यहां मेरा मुश्किल समाधान है। विचार cython की उपस्थिति को तब तक "छिपाना" है जब तक यह आवश्यकताओं द्वारा स्थापित नहीं किया जाता है। यह आलसी मूल्यांकन द्वारा हासिल किया जा सकता है।यहाँ एक उदाहरण है:

from setuptools import setup, Extension 

class lazy_cythonize(list): 
    def __init__(self, callback): 
     self._list, self.callback = None, callback 
    def c_list(self): 
     if self._list is None: self._list = self.callback() 
     return self._list 
    def __iter__(self): 
     for e in self.c_list(): yield e 
    def __getitem__(self, ii): return self.c_list()[ii] 
    def __len__(self): return len(self.c_list()) 

def extensions(): 
    from Cython.Build import cythonize 
    ext = Extension('native_ext_name', ['your/src/*.pyx']) 
    return cythonize([ext]) 


configuration = { 
    'name': 'mypackage', 
    'packages': ['yourpurepythonpackage'], 
    'install_requires': ['cython==0.17'], 
    'ext_modules': lazy_cythonize(extensions) 
} 

setup(**configuration) 

lazy_cythonize एक नकली सूची है कि अपने आंतरिक तत्वों जब कोई व्यक्ति इसे करने के लिए उपयोग करने के लिए कोशिश करता है उत्पन्न करता है।
जब इसकी आवश्यकता होती है, तो यह वर्ग Cython.Build आयात करता है और एक्सटेंशन की सूची उत्पन्न करता है। यह आपकी परियोजना में *.c फ़ाइलों को रखने से बचाता है, मॉड्यूल निर्माण करते समय साइथन स्थापित करने की आवश्यकता होती है।

काफी मुश्किल है, लेकिन असल में यह काम कर रहा है।

+2

कूल पैटर्न, यह setup_requires के साथ सेटअप रनटाइम के दौरान साइथन की आवश्यकता सेटअप सेटअप के साथ भी काम करता है :) – marscher

+0

यह वही है जो मैं ढूंढ रहा था। लंगड़ा स्थापित करने के लिए सिथॉन की आवश्यकता होती है, जब स्क्रिप्ट के शीर्ष पर साइथन आयात किया गया था। – csl

5

मैंने setuptools 288 के लिए एक फिक्स को धक्का दिया है, जिसे सेटअप 18.0 के रूप में रिलीज़ करने के लिए रखा गया है। This changelog entry ऐसी तकनीक का वर्णन करता है जो उस निर्माण के साथ काम करना चाहिए। एक beta release परीक्षण के लिए उपलब्ध है।

+0

क्या होगा यदि उपयोगकर्ता के पास सेटअपtools का पुराना संस्करण है? –

+0

@ रिचर्ड हान्सन आपके पास कुछ विकल्प हैं। आप या तो अपने उपयोगकर्ताओं को अपग्रेड करने की आवश्यकता हो सकती है (यह शायद इसके लिए बहुत जल्दी है), बंडल ez_setup.py और अपने पैकेज की स्थापना के दौरान setuptools अपग्रेड को बल दें (अनुशंसित नहीं), या सेटअपटोल संस्करण और कम सुरुचिपूर्ण दृष्टिकोण पर फ़ॉलबैक का पता लगाएं। –

+0

को अभी भी setuptools> = 18 में setup_requires deps (! = Cython) @ jasonR.Coombs – marscher

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

  • कोई संबंधित समस्या नहीं^_^