Distutils在可用SWIG扩展上失效:Python模块pip安装问题排查
没问题,咱们一步步来解决这个问题。用SWIG封装C库后通过distutils做pip安装,常见的坑主要集中在setup.py里的SWIG配置、外部库(比如liblapacke)的链接,还有MANIFEST.in没抓全必要文件这几个地方。下面是具体的修复方案:
1. 修正后的setup.py示例
这是适配你场景的setup.py,关键要把SWIG配置、外部库链接都做对:
from distutils.core import setup, Extension # 定义底层扩展模块(由SWIG生成) myExample_ext = Extension( '_myExample', # 注意:SWIG生成的扩展文件通常带下划线,比如_myExample.so sources=['myExample.i', '你的C库源文件.c'], # 必须包含SWIG接口文件和你的C库源码 swig_opts=['-c++'], # 如果你的C库用到C++就保留,纯C环境可以删掉 libraries=['lapacke'], # 明确指定链接liblapacke库 # 若liblapacke不在系统默认路径,解开下面两行并填写实际路径 # library_dirs=['/usr/local/lib'], # include_dirs=['/usr/local/include'], ) setup( name='myExample', version='0.1', description='用SWIG封装的C库Python模块', ext_modules=[myExample_ext], py_modules=['myExample'], # 要安装的上层Python接口模块(SWIG生成或你手写的) )
关键说明:
_myExample是SWIG生成的底层二进制模块名,而myExample.py是供用户调用的上层接口,所以py_modules必须包含它才能一起安装。sources里必须放SWIG的.i接口文件,distutils会自动调用SWIG生成对应的C包装代码,不用手动提前编译。libraries=['lapacke']告诉编译器在链接阶段引入liblapacke,确保依赖的功能能正常工作。
2. 正确配置MANIFEST.in
MANIFEST.in的作用是确保创建源码包时所有必要文件都被包含,避免pip安装时找不到文件:
# 包含SWIG接口文件 include myExample.i # 包含C库的源码和头文件(如果分散在子目录,用recursive-include) include *.c include *.h # 包含setup.py和上层Python接口文件 include setup.py include myExample.py
3. 排查与验证步骤
- 先本地编译测试:别直接用pip,先运行
python setup.py build_ext --inplace,这会把编译好的模块放在当前目录。然后打开Python交互环境试试import myExample,如果这里能正常运行,说明编译和链接没问题;如果报错,先解决基础问题(比如找不到lapacke就先安装依赖:Debian/Ubuntu用sudo apt-get install liblapacke-dev,macOS用brew install lapack)。 - 验证源码包完整性:运行
python setup.py sdist生成tar.gz源码包,打开看看里面是不是包含了所有需要的文件(.i、.c、.h、setup.py等),缺文件就调整MANIFEST.in。 - 用pip正式安装:确认本地测试没问题后,在项目根目录运行
pip install .,或者用生成的源码包安装pip install dist/myExample-0.1.tar.gz。
内容的提问来源于stack exchange,提问作者user5669394
相关产品推荐
相关产品推荐

