Sure !
(在下文中,我假设您已经知道如何处理cimport
以及之间的相互作用.pxd
and .pyx
。如果情况不完全如此,请询问,我也会开发该部分)
示例(从我的 C++ 项目中获取,但 C 项目的工作原理几乎相同):
1.Distutils安装文件:
假设要创建的扩展将被调用myext
第三方共享库是libexternlib.so
(注意lib*前缀,在这里)...
# 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/"]
)
]
)
Note :你的外在.so
文件通过以下方式链接libraries
选项 :
libraries=["externlib"] # Without the 'lib' prefix and the '.so' extension...
注:sources
选项可用于编译一些额外的源文件。
重要的 : myext.pxd
(不要与.pyd
- Windows 的东西)和myext.pyx
应该在同一目录中。在编译时,首先处理定义文件(如果存在)(more http://docs.cython.org/src/userguide/sharing_declarations.html).
2.然后运行如下:
将目录更改为包含您的目录后myext.pxd
, your 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
Where :
-
libexternlib.so
假设位于./some/path/to/externlib/
-
yourheader.h
假设位于./some/path/to/includes/
Note : CFLAGS
也可以使用设置extra_compile_args
选项 :
extra_compile_args=["-I./some/path/to/includes/", "-fopenmp", "-O3"]
Note : 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
...
Note关于优化:默认-O2
用于编译扩展,但这可能会被重载(参见上面的设置,其中-O3
已指定)。
Note关于 Cython 路径:如果 Cython 安装在自定义目录中,您可能需要首先将其添加到您的环境中:
PYTHONPATH=$PYTHONPATH:../../../DEPENDENCIES/Cython-0.18 export PYTHONPATH;
PATH=$PATH:../../../DEPENDENCIES/Cython-0.18/bin; export PATH;
好吧,希望我涵盖了要点......