Skip to main content
 首页 » 编程设计

python之如何编写 setup.py 来安装 SWIG 构建的 python 扩展(xxx.so 文件)

2025年05月04日16zhujiabin

使用 SWIG 构建 python 扩展 (xxx.so) 比 distutils 更容易.您不需要编写 wrap.c 程序来包装您的原始 c 程序。所以我更喜欢使用 SWIG 而不是 Distutils。但是没有方法可以通过编写 setup.py 文件来自动安装扩展(xxx.so)。这困扰了我很多天。

为了让题目解释的更清楚,我用Step的策略来表达清楚。

第一步:有原始的C/C++代码。然后使用 SWIG 创建 Python 包装器。

第 2 步:使用 Distuils(编写 setup.py)或仅使用 gcc 命令行来创建 Python 扩展文件。 Python 扩展名是 xxx.so。显然,在这一步中,您可以使用Distuils将编译和安装结合起来。

第 3 步:通过编写 setup.py 安装 xxx.so Python 扩展。

我只是不知道如何编写 setup.py 来安装 xxx.so Python 扩展的第 3 步。

有没有办法通过编写 setup.py 而不是使用 sys.path.append() 或 sys.path.insert() 方法来安装 python 扩展(xxx.so)?

非常感谢您提供的任何答案!

最后我尝试了STEP 2编译安装结合的方法。它可以正常工作,但我的目的不是只使用 setup.py 安装 _xxx.so Python 扩展。

目录结构:

setup.py 
src/ 
    libdemo/ 
        __init__.py 
        LibHello.py 
lib/ 
    palindrome.c   # original C code 
    palindrome_wrap.c  # Python wrapper built by SWIG 

setup.py代码:

#-*- coding:utf-8 -*- 
import sys 
import os 
from setuptools import setup, find_packages, Extension 
 
libPath = "lib" 
 
moduleLibPalindrome = Extension( 
      name = 'libdemo._palindrome',  
      sources = [os.path.join(libPath, 'palindrome_wrap.c'),  
            os.path.join(libPath, 'palindrome.c')] 
) 
setup ( 
      name = 'test_example', 
      version = '0.1', 
      author = "Hobart", 
      description = "Install extension from original C/C++", 
      packages= find_packages(where = 'src'), 
      package_dir = {'':'src'}, 
      ext_modules=[moduleLibPalindrome] 
) 

结果检查:

>>> from libdemo import _palindrome 
>>> dir(_palindrome) 
['SWIG_PyInstanceMethod_New', '__builtins__', '__doc__', '__file__',      '__name__', '__package__', 'is_palindrome'] 
>>> _palindrome.is_palindrome('asddsa') 
1 
>>>  

C代码源文件和_palindrome.so文件显示为following .您可以下载并在您的计算机上进行实验。

请您参考如下方法:

Distutils 不是关于编写 扩展,而是关于编译和安装它们。 SWIG 可以帮助您为 C/C++ 代码创建 Python 包装器,但不处理它们的编译和安装。

因此,distutils 可以(并且应该)用于安装 SWIG 生成的扩展。请参阅 using distutils 上的 SWIG 文档.

编辑:我对您要尝试做的事情感到有些困惑。通常,您会使用 distutils 来编译和安装您的扩展。这仍然可以通过调用

在两个单独的步骤中完成
python setup.py build_ext 
python setup.py install 

但是,如果我对您的理解正确,无论出于何种原因,您都有一个预编译的扩展(即 xxx.py 和 _xxx.so),并且希望仅使用例如安装它们distutils.

您可以使用 package_data distutils 的关键字,即以下 setup.py:

from distutils.core import setup 
setup (name = 'xxx', 
       version = '0.1', 
       author = "Nobody", 
       description = """Install precompiled extension""", 
       py_modules = ["xxx"], 
       packages=[''], 
       package_data={'': ['_xxx.so']}, 
       )