Ich versuche, eine darin geschriebene Bibliothek eines Drittanbieters zu integrieren C
Mit meinem python
Anwendung verwenden Cython
. Ich habe den gesamten Python-Code für einen Test geschrieben. Ich habe Probleme, ein Beispiel für die Einrichtung zu finden.
Ich habe ein pyd/pyx
Datei, die ich manuell erstellt habe. Der Dritte hat mir eine gegeben header file (*.h)
und ein shared library (*.so)
. Soweit ich das beurteilen kann, gibt es keine weiteren Abhängigkeiten. Kann jemand ein Beispiel geben, wie man dies mit Cython
und disutils
?
Vielen Dank
Sicher !
(Im Folgenden gehe ich davon aus, dass Sie bereits wissen, wie man damit umgeht cimport
und die Wechselwirkungen zwischen .pxd
und .pyx
. Wenn dies nicht vollständig der Fall ist, fragen Sie einfach und ich werde diesen Teil auch entwickeln.)
Das Beispiel (aus einem C++-Projekt von mir, aber ein C-Projekt würde ziemlich gleich funktionieren):
1. Die Setup-Datei von Distutils:
Angenommen, die zu erstellende Nebenstelle wird angerufen myext
und die gemeinsam genutzte Bibliothek des Drittanbieters ist libexternlib.so
(beachten Sie das lib* Präfix, hier) …
# setup.py file
import sys
import os
import shutil
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
# clean previous build
for root, dirs, files in os.walk(".", topdown=False):
for name in files:
if (name.startswith("myext") and not(name.endswith(".pyx") or name.endswith(".pxd"))):
os.remove(os.path.join(root, name))
for name in dirs:
if (name == "build"):
shutil.rmtree(name)
# build "myext.so" python extension to be added to "PYTHONPATH" afterwards...
setup(
cmdclass = {'build_ext': build_ext},
ext_modules = [
Extension("myext",
sources=["myext.pyx",
"SomeAdditionalCppClass1.cpp",
"SomeAdditionalCppClass2.cpp"
],
libraries=["externlib"], # refers to "libexternlib.so"
language="c++", # remove this if C and not C++
extra_compile_args=["-fopenmp", "-O3"],
extra_link_args=["-DSOME_DEFINE_OPT",
"-L./some/extra/dependency/dir/"]
)
]
)
Notiz : Ihre externe .so
Datei wird über die verknüpft libraries
Möglichkeit :
libraries=["externlib"] # Without the 'lib' prefix and the '.so' extension...
Beachten Sie das sources
Option kann verwendet werden, um einige zusätzliche Quelldateien zu kompilieren.
Wichtig : myext.pxd
(nicht verwechseln mit .pyd
– Windows-Zeug) und myext.pyx
sollte im selben Verzeichnis liegen. Zur Kompilierzeit wird die Definitionsdatei, falls vorhanden, zuerst verarbeitet (mehr).
2. Führen Sie es dann wie folgt aus:
Nachdem Sie das Verzeichnis in das geändert haben, das Ihre enthält myext.pxd
dein myext.pyx
sowie oben setup.py
Skript :
# setup.sh
# Make the "myext" Python Module ("myext.so")
CC="gcc" \
CXX="g++" \
CFLAGS="-I./some/path/to/includes/ -I../../../DEPENDENCIES/python2.7/inc -I../../../DEPENDENCIES/gsl-1.15" \
LDFLAGS="-L./some/path/to/externlib/" \
python setup.py build_ext --inplace
Wo :
libexternlib.so
wird als Standort angenommen ./some/path/to/externlib/
yourheader.h
wird als Standort angenommen ./some/path/to/includes/
Notiz : CFLAGS
könnte auch mit eingerichtet worden sein extra_compile_args
Möglichkeit :
extra_compile_args=["-I./some/path/to/includes/", "-fopenmp", "-O3"]
Notiz : LDFLAGS
könnte auch mit eingerichtet worden sein extra_link_args
Möglichkeit :
extra_link_args=["-L./some/path/to/externlib/", "-DSOME_DEFINE_OPT", "-L./some/extra/dependency/dir/"]
Sobald distutils mit dem Build fertig ist, erhalten Sie einige neue Dateien, insbesondere die myext.cpp
, myext.h
und vor allem die myext.so
.
3. Danach kann es losgehen:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./some/path/to/externlib/
export PYTHONPATH=$PYTHONPATH:./some/path/to/myext/
# Run some script requiring "myext.so"
python somescript.py
Wo Ihre neu erstellte Python-Erweiterung anhand ihres Namens importiert werden kann:
# somescript.py
import myext
from myext import PySomeFeature
...
Notiz über Optimierung: Standardmäßig -O2
wird zum Kompilieren der Erweiterung verwendet, diese kann jedoch überladen werden (siehe oben Setup where -O3
angegeben).
Notiz über Cython-Pfade : Wenn Cython in einem benutzerdefinierten Verzeichnis installiert wurde, möchten Sie es vielleicht zuerst zu Ihrer Umgebung hinzufügen:
PYTHONPATH=$PYTHONPATH:../../../DEPENDENCIES/Cython-0.18 export PYTHONPATH;
PATH=$PATH:../../../DEPENDENCIES/Cython-0.18/bin; export PATH;
Nun, ich hoffe, ich habe die wichtigsten Punkte abgedeckt …