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

不依赖distutils/setuptools制作可pip安装的Python模块

替代方案:无需distutils/setuptools制作可pip安装的SWIG C模块

好问题!既然没法依赖distutils或setuptools,咱们可以借助PEP 517/518定义的现代Python包构建规范,搭配第三方构建工具来实现pip可安装的包——完全绕开那俩老工具,还能完美适配你的SWIG封装C模块场景。下面是几个靠谱的方案:

方案1:Meson构建系统 + meson-python后端

Meson是轻量高效的构建工具,配合meson-python后端可以无缝对接pip的安装流程,专门适合处理C/C+++Python混合项目。

步骤:

  1. 编写meson.build配置文件,处理SWIG编译逻辑:
project('my_swig_module', 'c', 'python', version: '0.1.0')

# 找到Python环境
py = import('python')
python = py.find_installation()

# 声明SWIG模块
swig_mod = python.swig_module(
    name: 'my_module',
    interface_files: 'my_module.i',
    sources: 'my_c_code.c',
    # 如果你的C代码依赖其他库,这里可以加link_with参数
)

# 安装模块到Python的site-packages目录
install_subdir(
    swig_mod,
    install_dir: python.get_install_dir() / 'my_module'
)
  1. 编写pyproject.toml,告诉pip用meson-python作为构建后端:
[build-system]
requires = ["meson-python>=0.13.0"]
build-backend = "mesonpy"

[project]
name = "my_swig_module"
version = "0.1.0"
  1. 直接用pip安装:
pip install .

pip会自动下载meson-python,调用Meson完成SWIG编译、模块安装的全流程。

方案2:CMake + scikit-build-core后端

如果你更熟悉CMake,scikit-build-core是专门为Python项目设计的CMake集成后端,同样支持PEP 517规范,处理SWIG模块也很顺手。

步骤:

  1. 编写CMakeLists.txt配置SWIG编译:
cmake_minimum_required(VERSION 3.18)
project(my_swig_module)

# 找到Python和SWIG
find_package(Python REQUIRED COMPONENTS Interpreter Development)
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})

# 设置SWIG生成Python代码的参数
set(CMAKE_SWIG_FLAGS "-python")

# 声明SWIG模块
swig_add_library(my_module
    TYPE MODULE
    LANGUAGE python
    SOURCES my_module.i my_c_code.c
)

# 链接Python库
swig_link_libraries(my_module Python::Python)

# 安装模块到正确位置
install(TARGETS my_module
    DESTINATION ${Python_SITEARCH}
)
  1. 编写pyproject.toml指定scikit-build-core后端:
[build-system]
requires = ["scikit-build-core>=0.7.0"]
build-backend = "scikit_build_core.build"

[project]
name = "my_swig_module"
version = "0.1.0"
  1. 执行pip安装:
pip install .

方案3:自定义PEP 517构建后端(高度定制化)

如果上面的工具都不符合你的需求,还可以自己写一个极简的PEP 517构建后端,完全手动控制SWIG编译和文件复制流程。

示例(简化版):

  1. 编写build.py实现构建逻辑:
import os
import subprocess
import shutil
from setuptools import distutils  # 仅用其工具函数,不依赖核心构建流程

def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
    # 1. 运行SWIG生成Python绑定和C包装代码
    subprocess.run([
        "swig", "-python", "-o", "my_module_wrap.c", "my_module.i"
    ], check=True)
    
    # 2. 编译C代码(这里假设用gcc,可根据系统调整)
    python_include = distutils.sysconfig.get_python_inc()
    subprocess.run([
        "gcc", "-shared", "-fPIC",
        "-I" + python_include,
        "my_c_code.c", "my_module_wrap.c",
        "-o", "_my_module.so"
    ], check=True)
    
    # 3. 准备wheel内容
    wheel_name = "my_swig_module-0.1.0-cp310-cp310-linux_x86_64.whl"  # 根据实际环境调整
    wheel_path = os.path.join(wheel_directory, wheel_name)
    module_dir = os.path.join(wheel_directory, "my_swig_module")
    os.makedirs(module_dir, exist_ok=True)
    shutil.copy("_my_module.so", module_dir)
    shutil.copy("my_module.py", module_dir)
    
    # 4. 生成wheel(实际可借助wheel库简化打包逻辑)
    return wheel_name
  1. 编写pyproject.toml指定自定义后端:
[build-system]
requires = ["wheel"]
build-backend = "build"

[project]
name = "my_swig_module"
version = "0.1.0"

这个方案自由度最高,但需要你自己处理各种系统兼容性(比如不同编译器、Python版本的路径差异),适合对构建流程有特殊要求的场景。

注意事项

  • 确保系统中已经安装了SWIG和对应的C编译器(比如Linux下的gcc、macOS下的clang、Windows下的MSVC),pip在构建时会自动调用这些工具。
  • 测试安装时可以加--no-cache-dir参数,避免缓存干扰:pip install --no-cache-dir .
  • 如果你的模块有系统级依赖(比如某个C库),可以在pyproject.toml的[project.optional-dependencies]里添加提示,或者在构建脚本里做依赖检查。

内容的提问来源于stack exchange,提问作者user5669394

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:43:37