【发布时间】:2018-05-08 17:46:58
【问题描述】:
我有一堆 SWIG 接口(foo.i、bar.i 等)。我想使用 setuptools 将它们构建到我的平台(MS Windows)的 Python(3.6.4)模块中。该模块应包括 SWIG 生成的 Python 文件 (*.py)、二进制扩展 (*.pyd) 和编译的缓存 (*.pyc)。我的 setup.py 基本上是这样的:
from setuptools import setup, Extension
from pathlib import Path
paths=list(Path('.').glob('*.i'))
py=[path.stem for path in paths]
ext=[Extension('_' + path.stem, [str(path)]) for path in paths]
setup(py_modules=py, ext_modules=ext)
现在我通过以下步骤构建它:
python setup.py build_ext -I..\include --swig-opts="-I..\include -c++" -b pkg
python setup.py build_py -c -d pkg
echo. > pkg\__init__.py
使用这些步骤,我得到了我想要的,在pkg 目录下。
我的问题是:有没有办法使用setup.py 的单个调用来获得这种效果,例如setup.py build?我认为构建应该调用 build_ext,但是我看不到如何传递,例如 swig-opts 选项。
更新
通过 SWIG 选项已解决 (h/t @hoefling)。解决方案如下所示:
ext=[Extension(name='_' + path.stem,
sources=[str(path)],
swig_opts=['-I../include', '-c++'],
include_dirs=['../include'])
for path in paths]
然而,剥掉那层洋葱后,我现在可以看到下面的层,即:setup.py build 作为单个调用,想先运行build_py,然后是build_ext。你能明白为什么这会失败吗?我没有 Python 资源。我的模块中的 Python 脚本将由 SWIG 生成,但 SWIG 直到 build_ext 步骤才会运行。因此,我最终遇到了同样的问题,即如何在一次调用中构建模块。
C:\some\path> python setup.py build
running build
running build_py
file foo.py (for module foo) not found
file foo.py (for module foo) not found
running build_ext
building '_foo' extension
swigging foo.i to foo_wrap.cpp
swig.exe -python -I../include -c++ -o foo_wrap.cpp foo.i
creating build
creating build\temp.win-amd64-3.6
creating build\temp.win-amd64-3.6\Release
cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -I../include /EHsc /Tpfoo_wrap.cpp /Fobuild\temp.win-amd64-3.6\Release\foo_wrap.obj foo_wrap.cpp
Creating build\wib.win-amd64-3.6
link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /EXPORT:PyInit__foo build\temp.win-amd64-3.6\Release\foo_wrap.obj /IMPLIB:build\temp.win-amd64-3.6\Release\_foo.cp36-win_amd64.lib
Creating library build\temp.win-amd64-3.6\Release\_foo.cp36-win_amd64.lib and object build\temp.win-amd64-3.6\Release\_foo.cp36-win_amd64.exp
Generating code
Finished generating code
完成后,foo.py 存在于 foo.i 旁边的当前工作目录中,而 _foo.cp36-win_amd64.pyd 存在于 build\lib.win-amd64-3.6 下。 (仅供参考,为了保护专有信息,此记录略有编辑,例如,我没有显示所有命令回显的所有完整路径。而且我没有在源代码中包含 bar.i。)
澄清一下:
错误是这个:
File foo.py (for module foo) not found虽然所有必需的文件都存在于输出中,除了 foo.cp36-win_amd64.pyc 我可能没有,我必须手动将 foo.py 和 _foo.cp36-win_amd64.pyd 复制到一些新的目录来制作一个干净的 Python 模块。
【问题讨论】:
-
build_ext支持开箱即用的 SWIG,因此Extension(name, files, swig_opts=['-I../include', '-c++'])应该构建得很好。 -
@hoefling 这对于传递 SWIG 选项是正确的,谢谢。
-
至于其他错误 - 您可以发布完整的错误消息吗?只需将文本从终端复制并粘贴到您的问题中即可。
-
啊,我现在明白问题所在了。
标签: python python-3.x swig setuptools