J'essaie de compiler, d'installer et d'exécuter un package que nous appellerons myPackage
. Il contient un fichier *.pyx
Qui appelle la fonction fftw_set_timelimit()
de la bibliothèque fftw
. Actuellement, lorsque j'exécute un script clientScript.py
Qui importe le package, j'obtiens le message d'erreur suivant:
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
D'après ce que je comprends (je suis assez nouveau pour python et cython), la liaison avec la bibliothèque C n'est pas encore effectuée dans mon package. En effet, mon fichier setup.py
Ressemble à ce :
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"),
)
Comme vous pouvez le voir, mon fichier setup.py
Utilise setuptools
. J'ai décidé de le faire car il est recommandé par le Python Packaging User Guide . Cependant, les instructions de la documentation Cython utilisent distutils
à la place. La liaison des bibliothèques se fait via un appel à distutils.Extension('file',['file.pyx'],libraries='fftw')
. Comment obtenir le même résultat en utilisant setuptools
?
Il s'avère que setuptools
possède un module setuptools.extension.Extension
Qui est utilisé de la même manière que le module distutils.extension.Extension
.
Au final, le fichier setup.py
Ressemble à quelque chose comme:
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)
)
Voici un aperçu de mon répertoire d'installation:
.
├── MANIFEST.in
├── myPackage
│ └── myModule.pyx
├── README.rst
└── setup.py
où myModule.pyx
est le fichier qui appelle fftw_set_timelimit()
.
MANIFEST.in
Contient:
include myPackage/*.*
et README.rst
est un simple fichier texte brut.