2015-09-11 5 views
11

Ich versuche, ein Paket zu kompilieren, zu installieren und auszuführen, das wir myPackage aufrufen. Es enthält eine *.pyx-Datei, die die Funktion fftw_set_timelimit() aus der Bibliothek fftw aufruft. Zur Zeit, als ich ein Skript clientScript.py ausführen, die das Paket, das ich erhalte die folgende Fehlermeldung importiert:Verwenden von setuptools zum Erstellen eines Cython-Pakets, das eine externe C-Bibliothek aufruft

Traceback (most recent call last): 
    File "clientScript.py", line 5, in <module> 
    import myPackage.myModule 
ImportError: /usr/local/lib/python2.7/dist-packages/myPackage/myModule.so: undefined symbol: fftw_set_timelimit 

Von dem, was ich verstehe (ich bin ganz neu in Python und cython), die Verknüpfung mit der Bibliothek C ist noch nicht in meinem Paket durchgeführt. Tatsächlich sieht meine setup.py-Datei wie folgt:

from setuptools import setup,find_packages 
from Cython.Build import cythonize 
import os 

setup(
    name = "myPackage", 
    version = "0.0.1", 
    url = "none", 
    author = "me", 
    author_email = "[email protected]", 
    packages=find_packages(), 
    ext_modules = cythonize("pyClo/pyClo.pyx"), 
) 

Wie Sie meine setup.py Datei setuptools verwendet sehen. Ich entschied mich dafür, da es von der Python Packaging User Guide empfohlen wird. Die Anweisungen in der Cython documentation verwenden stattdessen distutils. Die Verknüpfung von Bibliotheken erfolgt über einen Aufruf an distutils.Extension('file',['file.pyx'],libraries='fftw'). Wie erreiche ich das gleiche Ergebnis mit setuptools?

Antwort

13

Es stellt sich heraus setuptools hat ein Modul setuptools.extension.Extension, das auf die gleiche Weise wie das distutils.extension.Extension Modul verwendet wird.

Am Ende der setup.py Datei sieht ungefähr so ​​aus:

from setuptools import setup, find_packages 
from setuptools.extension import Extension 
from Cython.Build import cythonize 

extensions = [ 
    Extension(
     "myPackage.myModule", 
     ["myPackage/myModule.pyx"], 
     include_dirs=['/some/path/to/include/'], # not needed for fftw unless it is installed in an unusual place 
     libraries=['fftw3', 'fftw3f', 'fftw3l', 'fftw3_threads', 'fftw3f_threads', 'fftw3l_threads'], 
     library_dirs=['/some/path/to/include/'], # not needed for fftw unless it is installed in an unusual place 
    ), 
] 

setup(
    name = "myPackage", 
    packages = find_packages(), 
    ext_modules = cythonize(extensions) 
) 

Hier eine Übersicht meiner Installationsverzeichnis:

. 
├── MANIFEST.in 
├── myPackage 
│   └── myModule.pyx 
├── README.rst 
└── setup.py 

wo myModule.pyx die Datei ist, die fftw_set_timelimit() aufruft.

MANIFEST.in enthält:

include myPackage/*.* 

und README.rst eine reine Textdatei ist.

+1

Nach [distutils Dokumentation] (https://docs.python.org/2/distutils/apiref.html#distutils.core.Extension), 'distutils.core.Extension' nimmt als erstes Argument: "_der vollständige Name der Erweiterung, einschließlich aller Pakete - dh kein Dateiname oder Pfadname, aber Python dotted name_" Deshalb sollte man statt "myPackage/myModule" '' myPackage.myModule "' haben. – SylM

+0

@SylM Ich habe Python seit einiger Zeit nicht mehr benutzt ... Es wird also etwas Aufwand für mich sein, zu überprüfen, ob der Schrägstrich "/" durch einen Punkt ersetzt wird. " wie Sie vorschlagen, funktioniert tatsächlich. Wenn Sie jedoch die Lösung testen und mir sagen, dass es in Ordnung ist, werde ich meine Antwort entsprechend bearbeiten. Mit "Testen der Lösung" möchte ich ein neues Projekt von Grund auf starten und dafür sorgen, dass es funktioniert. Möchten Sie das tun? ;) –

+0

@GLorieul Ich habe gerade die obige Vorlage mit der punktierten Namenssyntax verwendet und erfolgreich kompiliert. – Gilly

Verwandte Themen