如何在Linux上为Windows交叉编译Python扩展?
回答:简化Linux下Windows Cython扩展交叉编译流程
一、无需复杂扩展build_ext的简化方案
你完全不用手动去折腾build_ext的扩展逻辑——现在有更简洁的方式完成Windows Cython代码的交叉编译:
1. 直接指定交叉编译器
Cython和setuptools原生支持通过环境变量或配置参数指定交叉编译器,不用修改底层构建类:
- 环境变量快捷方式:运行构建命令前先设置编译器变量:
export CC=x86_64-w64-mingw32-gcc-win32 export CXX=x86_64-w64-mingw32-g++-win32 - setup.py配置方式:在定义Cython扩展时直接传入编译器参数,还能附带编译/链接选项:
from setuptools import setup from Cython.Build import cythonize setup( name="your_extension", ext_modules=cythonize( "your_module.pyx", compiler="x86_64-w64-mingw32-gcc-win32", extra_compile_args=["-pthread"], extra_link_args=["-lwinmm", "-lntdll", "-lws2_32"] ) )
2. 关联目标Windows Python的依赖
你只需要下载对应版本的Windows Python开发包(包含头文件和pythonXY.lib),然后在配置中指定路径即可:
ext_modules=cythonize( "your_module.pyx", compiler="x86_64-w64-mingw32-gcc-win32", include_dirs=["/path/to/windows/python/include"], library_dirs=["/path/to/windows/python/libs"], extra_link_args=["-lpython310", "-lwinmm", "-lntdll", "-lws2_32"] )
整个过程不需要深入setuptools/distutils的复杂交互,靠配置就能搞定。
二、2009年以来的技术变化
那篇旧文章的核心思路(指定交叉编译器、链接目标Python库)仍然成立,但现在的工具链已经简化了太多:
- 原生交叉编译支持:Cython和setuptools现在直接集成了交叉编译参数,不需要手动修改distutils的编译器类;
- 标准化构建流程:PEP 517/518引入的
pyproject.toml可以更清晰地声明构建依赖和编译器配置,替代旧的setup.py硬编码; - 自动化多平台工具:像
cibuildwheel这类工具可以在Linux上自动完成Windows、Linux等多平台的扩展编译,全程不需要手动配置环境; - 分发格式升级:现在官方推荐用wheel(PEP 427)替代egg,wheel支持平台标签(如
win_amd64、manylinux_x86_64),pip会自动识别并安装对应平台的版本,兼容性和易用性远胜egg。
所以你完全不需要严格按照旧文章的步骤来,现代工具已经把繁琐的流程自动化了。
三、参考示例项目
可以参考这些方向的项目:
- 成熟跨平台库:比如
cryptography、pywin32的部分组件,它们的pyproject.toml或构建脚本里有完整的交叉编译配置; - cibuildwheel官方示例:查看
cibuildwheel的文档示例,它能一键在Linux上生成多平台wheel包,完美匹配你的需求; - 小型开源项目:GitHub上搜索“mingw cross compile python cython”,能找到很多工具类库的极简配置,适合快速参考。
四、实现多平台自动部署的最佳实践
建议放弃egg,改用wheel作为分发格式:
- 在Linux上分别编译Linux和Windows版本的扩展(通过
--plat-name参数指定目标平台,比如python setup.py bdist_wheel --plat-name win_amd64); - 用
twine将多平台wheel上传到PyPI或私有仓库; - 用户通过pip安装时,会自动根据系统平台匹配对应的PE/ELF二进制包,完全无需手动干预。
内容的提问来源于stack exchange,提问作者wvxvw
相关产品推荐
相关产品推荐

