2014-06-05 9 views
12

Napisałem bibliotekę, której główna funkcjonalność jest zaimplementowana w C (szybkość jest krytyczna), z cienką warstwą Pythona wokół niej, aby poradzić sobie z złośliwością ctypes.Najlepszy sposób na spakowanie biblioteki Pythona zawierającej bibliotekę współużytkowaną języka C?

idę, aby go zapakować i zastanawiam się, jak mogę najlepiej iść na ten temat. Kod, z którym musi się połączyć, to biblioteka współdzielona. Mam plik Makefile, który tworzy kod C i tworzy plik .so, ale nie wiem, jak go skompilować za pomocą distutils. Należy po prostu zawołać make z subprocess nadrzędnymi komendy install (jeśli tak, to install miejsce na to, czy jest build bardziej odpowiednie?)

Aktualizacja: Chcę zwrócić uwagę, że jest to nie rozszerzenie Pythona. Oznacza to, że biblioteka C nie zawiera kodu interakcyjnego z modułem wykonawczym Python. Python wykonuje wywołania funkcji obcych do prostej biblioteki współdzielonej C.

+0

Masz jakieś rozwiązanie swojego problemu? Utknąłem z tym samym pytaniem i desperacko szukałem odpowiedzi;) – MrLeeh

+0

To jest bardzo dawno temu, ale wygląda na to, że rozwiązałem to przez wyłapanie na 'make'. To setup.py z tej biblioteki: https://gist.github.com/obeattie/3d491ec4c29b1d4b46387b285c91ca89 – obeattie

+0

próbowałem robić to, co masz w tym GIST, ale ... jak się dostać cię '.so' wyłożone, aby zainstalować w dowolnej lokalizacji Python/ld będzie go szukać? – wvxvw

Odpowiedz

2

Biorąc pod uwagę, że postępowano zgodnie z instrukcjami dotyczącymi create Python extensions in C, należy po prostu zarejestrować moduły rozszerzeń, jak w przypadku this documentation.
Więc skrypt setup.py z biblioteki powinien wyglądać następująco:

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

i distutils wie jak skompilować rozszerzenie C udostępnionej biblioteki, a ponadto gdzie go umieścić.

Oczywiście nie mam żadnych dalszych informacji o twojej bibliotece, więc prawdopodobnie chcesz dodać więcej argumentów do wywołania setup(...).

+0

@ElmoVanKielvo, czy wiesz, jak to zrobić w distutils2? – Mansueli

+1

Wydaje się, że ... http://pythonhosted.org/Distutils2/distutils/setupscript.html#describing-extension-modules ... dokładnie tak samo :) – ElmoVanKielmo

+5

To nie jest rozszerzenie Pythona. Jest to czysta biblioteka C (która nie zawiera samego kodu, który mógłby wchodzić w interakcje ze środowiskiem uruchomieniowym Python), ale Python wykonuje wywołania za pośrednictwem ['ctypes'] (https://docs.python.org/2/library/ctypes.html). Potencjalnie można owinąć bibliotekę współużytkowaną C w module rozszerzającym Pythona, ale wolę zachować bieżące podejście typu "ctypes". – obeattie

1

Pomyślę budowę modułu Pythona jako podprojekcie normalnej wspólnej budowy biblioteki. Tak więc użyj automake, autoconf lub czegoś podobnego, aby zbudować bibliotekę współdzieloną, mieć katalog python_bindings z setup.py i twój moduł python.

1

miałem podobną potrzebę i ta odpowiedź jest pomocna: Python setup.py call makefile don't include binaries.

Mam biblioteki ANSI C w katalogu mojej dystrybucji src. W katalogu src znajduje się plik Makefile, który tworzy plik o nazwie liblsd.so w moim katalogu pakietów (lsd). Wywołuję to w pliku setup.py, a następnie powiadamam program instalacyjny o dołączeniu pliku biblioteki za pomocą argumentu 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

Powinieneś przynajmniej podkatalogu 'distutils.command.build' i nadpisać metodę' run', w przeciwnym razie wywołanie make stanie się dla każdego typu wywołania setup.py, gdzie możesz nie chcieć przekompilować biblioteki (np. "lub" upload ") –

Powiązane problemy