如何用MinGW‑w64,将.py编译为.pyd

如何用MinGW‑w64,将.py编译为.pyd

一、创建虚拟环境

(有洁癖,不想在原始安装的python里面做任何操作)

Python创建虚拟环境的命令:
1 python -m venv venv_name
2 
3 D:\envir\python310\python -m venv D:\worksp\Python\venv\vpy310

给当前虚拟环境配置永久镜像:

在虚拟环境venv目录(跟Scripts目录平级)下创建创建 pip.ini 文件

[global]
# 虚拟环境专用源(清华源示例)
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
# 信任该源(避免 SSL 验证报错)
trusted-host = pypi.tuna.tsinghua.edu.cn
# 可选:添加额外的备用源(若主源访问失败,自动尝试)
extra-index-url = https://mirrors.aliyun.com/pypi/simple/

pip config list 会显示 pip 的完整配置(包括当前生效的源)

pip config list --verbose 会显示每个配置项来自哪个文件(比如用户目录的 pip.conf/pip.ini),方便排查多配置冲突。

二、编译

编译.py文件(将.py文件编译为.pyd文件)

第一步:安装cython

pip install cython 进行安装。(2025.11.30安装的版本是3.2.1)

第二步:安装 MinGW‑w64 编译器

问:为什么选择MinGW‑w64而不选择MSVC?答:因为在离线环境安装MSVC太困难了。

打开 https://github.com/niXman/mingw-builds-binaries/releases

选择:x86_64-15.2.0-release-posix-seh-ucrt-rt_v13-rev0.7z,解压即可(我是解压到D:\envir)。

设置环境变量:D:\envir\mingw64\bin

第三步:编写setup.py
 1 from setuptools import setup, Extension
 2 from Cython.Build import cythonize
 3  4 """
 5 关键说明:
 6 -DMS_WIN64:-D 是编译器的 “定义宏” 参数,这里表示给 MinGW 定义 MS_WIN64 宏;
 7 作用:让 Python 的 pyconfig.h 识别当前是 64 位 Windows 系统,走到正确的 64 位分支,定义 SIZEOF_VOID_P=8;
 8 -DSIZEOF_VOID_P=8:兜底定义 SIZEOF_VOID_P 为 8(64 位系统 void* 的字节数);
 9 作用:即使 MS_WIN64 宏未生效,也能强制覆盖 pyconfig.h 的定义,避免 “除零错误” 和 “枚举值非法”。
10 """
11 12 ext = Extension(
13     name="hello",  # 扩展模块的名称(Python 中 import 时用的名字,比如 import hello)
14     sources=["hello.py"],  # 要编译的源文件列表(Cython 脚本或 C 语言文件),可以是.py文件,或者将.py改为.pyx
15     include_dirs=[  # 头文件(.h)的搜索目录,告诉 MinGW 编译器 “去哪里找需要的头文件”(比如 Python 的 Python.h、pyconfig.h 等核心头文件)
16         "D:\\envir\\python310\\Include"
17     ],
18     library_dirs=["D:\\envir\\python310\\libs"],  # 库文件(.lib)的搜索目录,告诉 MinGW 编译器 “去哪里找需要的库文件”
19     # 关键:1. 定义 MS_WIN64,让 pyconfig.h 识别 64位;2. 兜底定义 SIZEOF_VOID_P=8
20     extra_compile_args=["-DMS_WIN64", "-DSIZEOF_VOID_P=8"]  # 额外的编译器参数(给 MinGW 传递的编译指令)
21 )
22 23 setup(
24     name="hello",
25     ext_modules=cythonize(
26         ext,
27         compiler_directives={"language_level": "3"}  # 告诉 Cython “按 Python 3 的语法规则编译”
28     )
29 )
30 31 # python setup.py build_ext --inplace

 

第四部:创建 setup.cfg 文件
[build_ext]
compiler = mingw32
# 但通常我们会把 “源文件、头文件路径” 等和项目强相关的配置写在 setup.py 中,把 “编译器选择” 这种工具链配置写在 setup.cfg 中,分离更清晰。
# 下面2行仅仅是示例
include_dirs = D:\envir\python310\Include  # 头文件目录(也可在 setup.py 中配置)
library_dirs = D:\envir\python310\libs    # 库文件目录(也可在 setup.py 中配置)

 

作用:告诉 Python 的 setuptools 工具:编译扩展模块(.pyd/.so)时,强制使用 MinGW 编译器,而非默认的 MSVC(Visual C++)编译器—— 这是摆脱 “需要 VS C++ 14.0+” 错误、用 MinGW 成功编译的核心配置之一。

替代方法:命令行参数直接指定,编译时在命令行末尾加 --compiler=mingw32

python setup.py build_ext --inplace --compiler=mingw32

第五步:构建命令

python setup.py build_ext --inplace

python要么用绝对路径,要么在其所在文件夹中打开cmd

第六步:文件生成

运行命令之后,会生成build文件夹,hello.chello.cp310-win_amd64.pyd

  • 有用的文件:只需要保留 hello.cp310-win_amd64.pyd(可直接导入使用);

  • 可删除的文件:hello.c(中间文件)、build 文件夹(临时文件),删除后不影响使用,下次编译会自动重建;

重命名说明

hello.cp310-win_amd64.pyd 的结构可拆分为:[模块名].[版本标识].[平台标识].pyd(其中 版本标识平台标识 是可选的,Python 导入时会忽略这两部分,只认 模块名

去掉 版本标识平台标识,直接改成 hello.pyd(最简洁,推荐)

如把 hello.cp310-win_amd64.pyd 改成 my_hello.pyd,则导入时必须用 import my_hello,不能再用 import hello

posted @ 2025-11-30 13:46  breezecool  阅读(0)  评论(0)    收藏  举报