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

如何使用scikit-build-core构建混合Cython与Python的项目?

如何使用scikit-build-core构建混合Cython与Python的项目?

我完全懂你现在的困扰——之前用setup.py能顺顺利利打包混合Cython和Python的项目,转用scikit-build-core后,不仅嵌套目录里的Cython文件编译不出来,最终wheel里的文件结构也完全不对。别着急,咱们一步步调整配置,把这个问题解决掉。

首先要确认一个前提:你的src/example目录和src/example/c目录下都要有空的__init__.py文件,这样Python才能把它们识别为合法的包,这是打包的基础。

接下来咱们逐个修改配置文件:

1. 调整pyproject.toml,确保Python包被正确识别

在[project]区块里添加包的声明,让构建工具明确要处理哪些Python包:

[project]
name = "example"
version = "0.1.0"
description = "Add your description here"
authors = [
    { name = "Colinxu2020", email = "colinxu2020@gmail.com" }
]
# 新增这一行,指定要打包的包
packages = ["example", "example.c"]

[tool.scikit-build]
minimum-version = "build-system.requires"
build-dir = "build/{wheel_tag}"

[build-system]
requires = ["scikit-build-core>=0.10", "cython", "cython-cmake"]
build-backend = "scikit_build_core.build"

2. 重写CMakeLists.txt,递归处理所有Cython文件并正确安装Python源码

之前的CMake脚本只处理了单个文件,而且模块命名和安装路径都不符合包结构要求,咱们改成递归处理所有pyx文件,同时把Python源码也安装到对应位置:

cmake_minimum_required(VERSION 3.21)
project(${SKBUILD_PROJECT_NAME} LANGUAGES CXX)

find_package(
  Python
  COMPONENTS Interpreter Development.Module
  REQUIRED)
include(UseCython)

# 递归查找所有src/example下的pyx文件
file(GLOB_RECURSE pyx_files src/example/**/*.pyx)

foreach(pyx_file ${pyx_files})
  # 将pyx文件转译为C++文件
  cython_transpile(${pyx_file} LANGUAGE CXX OUTPUT_VARIABLE cpp_file)
  
  # 生成符合包结构的模块名称:比如src/example/c/e.pyx → example.c.e
  string(REPLACE "${CMAKE_SOURCE_DIR}/src/example/" "" module_path ${pyx_file})
  string(REPLACE ".pyx" "" module_name ${module_path})
  string(REPLACE "/" "." module_name ${module_name})
  
  # 创建Python扩展模块
  python_add_library(${module_name} MODULE WITH_SOABI "${cpp_file}")
  
  # 将编译后的模块安装到对应的包目录下
  install(TARGETS ${module_name} 
          DESTINATION example/${module_path})
endforeach()

# 安装所有Python源码文件(.py)
file(GLOB_RECURSE py_files src/example/**/*.py)
foreach(py_file ${py_files})
  # 计算文件的安装路径,保持原目录结构
  string(REPLACE "${CMAKE_SOURCE_DIR}/src/example/" "" install_path ${py_file})
  get_filename_component(install_dir ${install_path} DIRECTORY)
  install(FILES ${py_file} 
          DESTINATION example/${install_dir})
endforeach()

3. 清理缓存并测试构建

先删除之前的build目录和dist目录,避免旧缓存干扰,然后用uv构建:

uv build --clean

构建完成后,你会在dist目录得到正确的wheel文件,安装测试一下:

uv install dist/example-0.1.0-*.whl

这样生成的wheel文件结构就会和你用setup.py生成的一致了:

  • example/a.py
  • example/b.pyd
  • example/c/d.py
  • example/c/e.pyd

备注:内容来源于stack exchange,提问作者colinxu2020

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 17:39:33