使用MinGW从Linux交叉编译Python扩展至Windows遇问题求助
解决Linux下MinGW交叉编译Windows Python扩展的问题
我来帮你搞定这个交叉编译的坑,你遇到的两个问题本质都是环境配置没跟上交叉编译的需求,咱们一步步解决:
1. 让Python正确调用MinGW交叉编译器
你第一次执行python setup.py build_ext --compiler=mingw32时,Python的distutils误以为是在Windows本地编译,所以给Linux版gcc传了Windows专属的-mdll参数,这肯定会报错。要解决这个,得明确告诉distutils我们是在交叉编译,指定目标平台和交叉编译器:
方法一:通过环境变量指定
直接在执行命令前设置环境变量,强制用MinGW交叉编译器:
export CC=/usr/bin/mingw32-gcc export CXX=/usr/bin/mingw32-g++ export LD=/usr/bin/mingw32-ld python setup.py build_ext --compiler=mingw32 --host=mingw32
这里的--host=mingw32是核心,它告诉distutils我们要编译给Windows平台用,而不是当前的Linux。
方法二:修改setup.py强制指定编译器
如果环境变量的方式不稳定,可以直接在setup.py里定义交叉编译器类:
from distutils.core import setup from distutils.extension import Extension from distutils.command.build_ext import build_ext from distutils.cygwinccompiler import Mingw32CCompiler # 自定义交叉编译类 class CrossMingwCompiler(Mingw32CCompiler): def __init__(self, verbose=0, dry_run=0, force=0): super().__init__(verbose, dry_run, force) # 指定交叉编译器路径 self.cc = "/usr/bin/mingw32-gcc" self.cxx = "/usr/bin/mingw32-g++" self.linker_exe = "/usr/bin/mingw32-gcc" self.linker_so = "/usr/bin/mingw32-gcc" # 自定义build_ext命令 class CrossBuildExt(build_ext): def _get_compiler(self): return CrossMingwCompiler() # 你的扩展配置 ext_modules = [ Extension("your_module", sources=["your_source.c"]) ] setup( name="your_package", ext_modules=ext_modules, cmdclass={"build_ext": CrossBuildExt} )
这样执行python setup.py build_ext时,就会直接用你指定的MinGW交叉编译器,不会再调用本地gcc。
2. 替换为Windows版Python的头文件和库
你第二次报错是因为用了Linux编译的Python头文件,里面包含了POSIX特有的sys/select.h,而MinGW编译Windows程序根本不需要这个。解决办法是用Windows版Python的开发文件:
- 下载对应版本的Windows Python安装包(比如你用的Python 2.7.13,就下Windows x86的安装包),解压后找到
include和libs目录。 - 编译时指定这些Windows版的路径:
python setup.py build_ext --compiler=mingw32 --host=mingw32 \ --include-dirs=/path/to/windows-python/include \ --library-dirs=/path/to/windows-python/libs
这样编译器就会加载Windows Python的头文件,不会再引入Linux特有的POSIX头文件了。
额外注意事项
- 确保你的MinGW工具链完整:如果是编译64位Windows程序,要装
mingw-w64;32位的话装mingw32,并且确保安装了所有必要组件(比如有些发行版有mingw32-libpython2.7包,直接装这个就能拿到Windows Python的头文件和库,不用手动下载)。 - 编译出来的扩展是
.pyd格式,要放到Windows的Python环境里测试,Linux上没法直接运行。 - 如果可以的话,尽量用Python 3来交叉编译,它的distutils对交叉编译的支持比Python 2.7更完善。
内容的提问来源于stack exchange,提问作者rakwaht




