我正在尝试使用C
将python
中编写的第三方库与我的Cython
应用程序集成。我有为测试编写的所有python代码。我找不到设置它的例子。
我有一个手动创建的pyd/pyx
文件。第三方给了我一个header file (*.h)
和一个shared library (*.so)
。据我所知,没有其他依赖。有人可以提供一个如何使用Cython
和disutils
设置此内容的示例吗?
由于
答案 0 :(得分:54)
当然!
(在下文中,我假设您已经知道如何处理cimport
以及.pxd
和.pyx
之间的互动。如果情况并非完全如此,请询问并我也将开发那部分)
样本(从我的C ++项目中获取,但C项目的工作方式基本相同):
<强> 1。 Distutils设置文件:
假设要创建的扩展名为myext
,第三方共享库为libexternlib.so
(请注意 lib * 前缀,此处)... < / p>
# 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/"]
)
]
)
注意:您的外部.so
文件是通过libraries
选项关联的:
libraries=["externlib"] # Without the 'lib' prefix and the '.so' extension...
注意:sources
选项可用于获取一些其他源文件。
重要提示: myext.pxd
(不要与.pyd
- Windows内容混淆)和myext.pyx
应位于同一目录中。在编译时,定义文件(如果存在)首先被处理(more)。
<强> 2。然后按如下方式运行:
将目录更改为包含myext.pxd
,myext.pyx
以及上述setup.py
脚本的目录后:
# 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
其中:
libexternlib.so
位于./some/path/to/externlib/
yourheader.h
位于./some/path/to/includes/
注意:也可以使用CFLAGS
选项设置 extra_compile_args
:
extra_compile_args=["-I./some/path/to/includes/", "-fopenmp", "-O3"]
注意:也可以使用LDFLAGS
选项设置 extra_link_args
:
extra_link_args=["-L./some/path/to/externlib/", "-DSOME_DEFINE_OPT", "-L./some/extra/dependency/dir/"]
使用构建完成distutils后,您会收到一些新文件,特别是myext.cpp
,myext.h
,最重要的是myext.so
。
第3。在那之后,你很高兴:
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
可以通过名称导入新创建的Python扩展名:
# somescript.py
import myext
from myext import PySomeFeature
...
关于优化的 注意:默认情况下,-O2
用于编译扩展程序,但这可能会过载(请参阅上面的设置,其中指定了-O3
。)
注意:如果Cython安装在自定义目录中,您可能希望将它添加到您的环境中,然后才能:
PYTHONPATH=$PYTHONPATH:../../../DEPENDENCIES/Cython-0.18 export PYTHONPATH;
PATH=$PATH:../../../DEPENDENCIES/Cython-0.18/bin; export PATH;
嗯,希望我涵盖了要点......