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

如何在Python Wheel中处理.pyd扩展与.exe二进制脚本?

问题

我借助PyBind11用C++开发了一个Python二进制扩展,附带一个常规可执行文件(mytool.exe)。目前在制作用于分发的Wheel文件时遇到问题:使用pyproject.toml和setuptools后端能正常打包纯Python包及Python脚本,但不知如何处理包含整个扩展包的.pyd文件。目前能实现的最佳效果是将.pyd安装到python-install-dir/Lib/site-packages/mypackage/mypackage.pyd,此时需通过mypackage.mypackage.mymember访问成员;但手动将.pyd放到python-install-dir/Lib/site-packages/mypackage.pyd时,可通过mypackage.mymember正常访问。请问如何配置pyproject.toml实现该效果?是否在.pyd文件中有遗漏?或者是否需要更换构建后端?另外,如何将mytool.exe包含到Wheel中,使其安装后位于python-install-dir/Scripts目录?

解决方案

一、调整.pyd文件的安装路径,实现直接导入

不需要更换构建后端,setuptools完全可以处理,核心是让.pyd直接安装到site-packages根目录而非子包目录,步骤如下:

  1. 确认PyBind11模块命名
    在你的C++代码中,确保PyBind11的模块名称为mypackage(即你期望的顶层包名):

    PYBIND11_MODULE(mypackage, m) {
        // 模块绑定代码
        m.def("mymember", []() { /* 实现逻辑 */ });
    }
    

    编译后生成的.pyd文件应为mypackage.pyd,而非嵌套命名的文件。

  2. 配置pyproject.toml
    修改配置,让setuptools将.pyd作为顶层模块安装:

    [project]
    name = "mypackage"
    version = "0.1.0"
    
    [tool.setuptools]
    # 不声明子包,因为要将.pyd作为顶层模块
    packages = []
    # 指定顶层扩展模块
    py-modules = ["mypackage"]
    
    # 如果是预编译好的.pyd,指定其本地路径
    [tool.setuptools.package-data]
    "" = ["mypackage.pyd"]
    
    # 如果是通过setuptools直接编译C++源文件,替换为以下配置:
    # [tool.setuptools.ext_modules]
    # mypackage = { sources = ["src/your_source.cpp"] }
    

    打包安装后,.pyd会被放置到site-packages/mypackage.pyd,即可直接通过import mypackage; mypackage.mymember访问。

二、将mytool.exe打包到Scripts目录

在pyproject.toml中添加data-files配置,指定可执行文件的目标路径为Scripts:

[tool.setuptools.data-files]
# 键为安装后的目标目录,值为本地文件的路径
"Scripts" = ["path/to/your/mytool.exe"]

安装Wheel后,mytool.exe会被自动复制到Python安装目录下的Scripts文件夹,该目录通常已加入系统PATH,可直接在终端运行mytool命令。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 01:52:49