如何让setuptools构建的多扩展库存放在对应模块目录?
问题:SWIG扩展库生成的二进制文件未存入对应模块目录
我有一个已通过SWIG完成Python封装并发布到PyPI的C++项目,使用setuptools构建多个扩展时,SWIG生成的二进制文件直接放在项目根目录,而非对应模块的目录下。
当前构建后的目录结构
example_project/ ├── setup.py ├── _module1.cpython-310-x86_64-linux-gnu.so ├── _module2.cpython-310-x86_64-linux-gnu.so ├── _module3.cpython-310-x86_64-linux-gnu.so └── pyAPI/ ├── module1/ │ ├── __init__.py │ ├── module1.i │ └── module1.py ├── module2/ │ ├── __init__.py │ ├── module2.i │ └── module2.py └── module3/ ├── __init__.py ├── module3.i └── module3.py
期望的目录结构
example_project/ ├── setup.py └── pyAPI/ ├── module1/ │ ├── __init__.py │ ├── module1.i │ ├── module1.py │ └── _module1.cpython-310-x86_64-linux-gnu.so ├── module2/ │ ├── __init__.py │ ├── module2.i │ ├── module2.py │ └── _module2.cpython-310-x86_64-linux-gnu.so └── module3/ ├── __init__.py ├── module3.i ├── module3.py └── _module3.cpython-310-x86_64-linux-gnu.so
原setup.py仅声明扩展的源文件和swig_opts,通过ext_modules=[module1,module2,module3]调用,未配置路径相关参数。
解决方案
解决核心是给每个扩展模块指定完整的包路径,并通过SWIG参数控制生成文件的输出目录,具体步骤如下:
1. 修改扩展模块的name参数
将每个Extension的name设置为包含包层级的完整路径,比如pyAPI.module1._module1,这样setuptools会将生成的.so文件放到对应模块目录下。
2. 调整SWIG的-outdir参数
在swig_opts中添加-outdir,指定生成的Python包装器文件(module1.py等)输出到对应模块目录,避免路径错误。
3. 配置packages参数
确保setup函数中指定packages=find_packages(),自动识别并包含所有子模块。
修改后的setup.py示例
from setuptools import setup, Extension, find_packages # 定义每个扩展模块 module1_ext = Extension( name='pyAPI.module1._module1', # 完整包路径 sources=['pyAPI/module1/module1.i', 'path/to/your/cpp/module1.cpp'], swig_opts=[ '-c++', '-outdir', 'pyAPI/module1/', # 指定输出目录到对应模块 # 其他SWIG参数... ], # 其他编译参数(如include_dirs等)... ) module2_ext = Extension( name='pyAPI.module2._module2', sources=['pyAPI/module2/module2.i', 'path/to/your/cpp/module2.cpp'], swig_opts=[ '-c++', '-outdir', 'pyAPI/module2/', ], ) module3_ext = Extension( name='pyAPI.module3._module3', sources=['pyAPI/module3/module3.i', 'path/to/your/cpp/module3.cpp'], swig_opts=[ '-c++', '-outdir', 'pyAPI/module3/', ], ) setup( name='your-project-name', version='1.0.0', packages=find_packages(), # 自动发现所有子包 ext_modules=[module1_ext, module2_ext, module3_ext], # 其他setup参数(如author, description等)... )
验证效果
运行以下命令构建扩展:
python setup.py build_ext --inplace
构建完成后,生成的.so文件会自动存入对应模块目录,与期望结构一致。
内容的提问来源于stack exchange,提问作者aaries
相关产品推荐
相关产品推荐

