setuptools:从 C++ 代码构建共享库,然后构建链接到共享库的 Cython 包装器
setuptools: build shared library from C++ code, then build Cython wrapper linked to shared library
我们有一堆带有 类 的 C++ 文件,我们使用 Cython 包装到 Python。我们使用 setuptools 来构建 Cython 扩展。这一切都很好,我们按照这里的指南进行操作:
http://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html
我们基本上就是在做这样的事情
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize(
"rect.pyx", # our Cython source
sources=["Rectangle.cpp"], # additional source file(s)
language="c++", # generate C++ code
))
我们不喜欢这一点,因为我们必须重新编译所有内容,即使只有 Cython 部分发生变化,rect.pyx
在本例中也是如此。事实上我们从不接触 .cpp
文件,但经常更改 .pyx
文件。
我们想将.cpp
个文件单独编译成一个静态库或共享库,然后单独构建.pyx
个文件,链接到.cpp
个文件生成的库。使用 make
或 cmake
,所有这一切都会很容易,但我们想要一个仅使用 setuptools
的纯 Python 解决方案。模型代码看起来像这样:
from distutils.core import setup
from Cython.Build import cythonize
class CppLibary:
# somehow get that to work
# this should only recompile cpplib when source files changed
cpplib = CppLibary('cpplib',
sources=["Rectangle.cpp"], # put static cpp code here
include_dirs=["include"])
setup(ext_modules = cythonize(
"rect.pyx", # our Cython source
libraries=[cpplib], # link to cpplib
language="c++", # generate C++ code
))
setup
有一个看似没有记载的特性可以做到这一点,例如:
import os
from setuptools import setup
from Cython.Build import cythonize
ext_lib_path = 'rectangle'
include_dir = os.path.join(ext_lib_path, 'include')
sources = ['Rectangle.cpp']
# Use as macros = [('<DEFINITION>', '<VALUE>')]
# where value can be None
macros = None
ext_libraries = [['rectangle', {
'sources': [os.path.join(ext_lib_path, src) for src in sources],
'include_dirs': [include_dir],
'macros': macros,
}
]]
extensions = [Extension("rect",
sources=["rect.pyx"],
language="c++",
include_dirs=[include_dir],
libraries=['rectangle'],
)]
setup(ext_modules=cythonize(extensions),
libraries=ext_libraries)
libraries
参数构建在目录 rectangle
中找到的外部库,包含目录 rectangle/include
在它和扩展之间是公共的。
还已将导入从 distutils
切换到 setuptools
,后者已弃用,现在是 setuptools 的一部分。
没有看到关于此参数的任何文档,但看到它在其他项目中的使用。
这个是未经测试的,如果不行请提供示例文件进行测试。
我们有一堆带有 类 的 C++ 文件,我们使用 Cython 包装到 Python。我们使用 setuptools 来构建 Cython 扩展。这一切都很好,我们按照这里的指南进行操作: http://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html
我们基本上就是在做这样的事情
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize(
"rect.pyx", # our Cython source
sources=["Rectangle.cpp"], # additional source file(s)
language="c++", # generate C++ code
))
我们不喜欢这一点,因为我们必须重新编译所有内容,即使只有 Cython 部分发生变化,rect.pyx
在本例中也是如此。事实上我们从不接触 .cpp
文件,但经常更改 .pyx
文件。
我们想将.cpp
个文件单独编译成一个静态库或共享库,然后单独构建.pyx
个文件,链接到.cpp
个文件生成的库。使用 make
或 cmake
,所有这一切都会很容易,但我们想要一个仅使用 setuptools
的纯 Python 解决方案。模型代码看起来像这样:
from distutils.core import setup
from Cython.Build import cythonize
class CppLibary:
# somehow get that to work
# this should only recompile cpplib when source files changed
cpplib = CppLibary('cpplib',
sources=["Rectangle.cpp"], # put static cpp code here
include_dirs=["include"])
setup(ext_modules = cythonize(
"rect.pyx", # our Cython source
libraries=[cpplib], # link to cpplib
language="c++", # generate C++ code
))
setup
有一个看似没有记载的特性可以做到这一点,例如:
import os
from setuptools import setup
from Cython.Build import cythonize
ext_lib_path = 'rectangle'
include_dir = os.path.join(ext_lib_path, 'include')
sources = ['Rectangle.cpp']
# Use as macros = [('<DEFINITION>', '<VALUE>')]
# where value can be None
macros = None
ext_libraries = [['rectangle', {
'sources': [os.path.join(ext_lib_path, src) for src in sources],
'include_dirs': [include_dir],
'macros': macros,
}
]]
extensions = [Extension("rect",
sources=["rect.pyx"],
language="c++",
include_dirs=[include_dir],
libraries=['rectangle'],
)]
setup(ext_modules=cythonize(extensions),
libraries=ext_libraries)
libraries
参数构建在目录 rectangle
中找到的外部库,包含目录 rectangle/include
在它和扩展之间是公共的。
还已将导入从 distutils
切换到 setuptools
,后者已弃用,现在是 setuptools 的一部分。
没有看到关于此参数的任何文档,但看到它在其他项目中的使用。
这个是未经测试的,如果不行请提供示例文件进行测试。