You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 05:25:16