2014-06-05 28 views
12

Ho scritto una libreria la cui funzionalità principale è implementata in C (la velocità è critica), con un sottile strato Python attorno ad esso per gestire la cattiveria ctypes.Il modo migliore per impacchettare una libreria Python che include una libreria condivisa C?

Sto arrivando per impacchettarlo e mi chiedo come potrei andare meglio su questo. Il codice con cui deve interfacciarsi è una libreria condivisa. Ho un Makefile che costruisce il codice C e crea il file .so, ma non so come lo compili via distutils. Devo solo chiamare a make con subprocess sovrascrivendo il comando install (in tal caso, è install il posto per questo, o è build più appropriato?)

Aggiornamento: voglio sottolineare che questo non è un'estensione Python. Cioè, la libreria C non contiene alcun codice per interagire con il runtime di Python. Python sta facendo chiamate di funzioni estranee a una libreria condivisa C diritta.

+0

Avete qualche soluzione per il vostro problema? Sono bloccato con la stessa domanda e alla disperata ricerca di una risposta;) – MrLeeh

+0

Questo è molto tempo fa ma sembra che l'ho risolto eseguendo il bombardamento su 'make'. Questo è il setup.py di quella libreria: https://gist.github.com/obeattie/3d491ec4c29b1d4b46387b285c91ca89 – obeattie

+0

Ho provato a fare quello che hai in questo senso, ma ... come hai ottenuto il '.so' tu? foderato per essere installato in qualsiasi posizione Python/ld lo cercherà? – wvxvw

risposta

2

Dato che hai seguito le istruzioni su come create Python extensions in C, dovresti semplicemente arruolare i moduli di estensione come in this documentation.
Quindi lo script setup.py della libreria dovrebbe essere simile a questo:

from distutils.core import setup, Extension 
setup(
    name='your_python_library', 
    version='1.0', 
    ext_modules=[Extension('your_c_extension', ['your_c_extension.c'])], 
) 

e distutils sa come compilare il proprio interno per libreria C condivisa e per di più dove metterlo.

Ovviamente non ho ulteriori informazioni sulla libreria, quindi probabilmente vorrai aggiungere altri argomenti alla chiamata setup(...).

+0

@ElmoVanKielvo, sai come farlo in distutils2? – Mansueli

+1

Sembra tipo ... http://pythonhosted.org/Distutils2/distutils/setupscript.html#describing-extension-modules ... esattamente lo stesso :) – ElmoVanKielmo

+5

Non è un'estensione Python. Questa è una libreria C pura (che non contiene codice per interagire con il runtime di Python), ma Python effettua chiamate tramite ['ctypes'] (https://docs.python.org/2/library/ctypes.html). È potenzialmente possibile avvolgere la libreria condivisa C in un modulo di estensione Python, ma preferirei mantenere l'attuale approccio 'ctypes'. – obeattie

1

Vorrei prendere in considerazione la costruzione del modulo python come sottoprogetto di una normale build di libreria condivisa. Quindi, usa automake, autoconf o qualcosa di simile per costruire la libreria condivisa, avere una directory python_bindings con un setup.py e il tuo modulo python.

1

Avevo un'esigenza simile e ho trovato utile questa risposta: Python setup.py call makefile don't include binaries.

Ho una libreria ANSI C nella directory src della mia distribuzione. Nella directory src è un Makefile che crea un file chiamato liblsd.so nella mia directory dei pacchetti (lsd). Lo chiamo in setup.py e poi dico al setup di includere il file della libreria usando l'argomento package_data.

import os.path 
import subprocess 

from setuptools import setup 

with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as f: 
    readme = f.read() 

subprocess.call(['make', '-C', 'src']) 

setup(name='LSD', 
    version='0.0.1', 
    description='Python bindings for the LSD line segment detector.', 
    long_description=readme, 
    author='Geoff Hing', 
    author_email='[email protected]', 
    url='https://github.com/ghing/python-lsd', 
    packages=['lsd'], 
    package_data={'lsd': ['liblsd.so']}, 
    include_package_data=True, 
    classifiers=[ 
     'Development Status :: 1 - Planning', 
     'Intended Audience :: Developers', 
     'License :: OSI Approved :: MIT License', 
     'Operating System :: OS Independent', 
     'Programming Language :: Python', 
     'Programming Language :: C', 
     ], 
) 
+1

Dovresti almeno sub class 'distutils.command.build' e sovrascrivi il metodo' run', altrimenti la chiamata make avverrà per ogni tipo di chiamata a setup.py dove potresti non voler ricompilare la libreria (es. "o" carica ") –

Problemi correlati