Anaconda Py3.6+MinGW32编译Pyd模块失败:ld.exe报DEF文件语法错误
我之前在Anaconda环境下用MinGW编译Cython模块时也碰到过一模一样的问题——明明DEF文件看起来没毛病,ld.exe却硬说第一行有语法错误。结合你的情况,大概率是格式细节或者工具链适配的问题,给你几个靠谱的排查和解决方向:
检查DEF文件的换行格式
Windows系统默认用CRLF换行,但Anaconda生成DEF文件时偶尔会输出Unix风格的LF换行,而老版本的MinGW32 ld对这种格式兼容性很差。你可以用Notepad++打开报错的DEF文件,看右下角的换行标识,如果是LF,改成CRLF后再重新编译试试。确认cygwinccompiler.py的修改是否到位
你参考的那篇文章的核心是修改get_msvcr()函数,但很多人容易改得不彻底。打开Anaconda安装目录下Lib\distutils\cygwinccompiler.py,找到get_msvcr()函数,把原本返回MSVC运行时库的代码注释掉,改成返回空列表,比如:def get_msvcr(): # 适配MinGW,不再返回MSVC运行时依赖 return []修改后一定要保存,然后重启你的Anaconda终端再尝试编译。
给ld添加修复参数
有些MinGW32的ld版本对stdcall符号的解析有bug,会误判DEF文件的语法。你可以在setup.py里给链接器添加--enable-stdcall-fixup参数,强制ld修复符号解析问题:from distutils.core import setup from Cython.Build import cythonize setup( ext_modules=cythonize("_mssql.pyx"), extra_link_args=['--enable-stdcall-fixup'] )检查目标文件的符号是否异常
虽然_mssql.o大小正常,但可以用MinGW自带的objdump工具检查符号表,看看有没有奇怪的符号导致DEF文件生成异常:objdump -x _mssql.o > symbols.txt打开symbols.txt看看有没有格式异常的符号定义,这类问题也会间接导致DEF文件报错。
调整MinGW32版本
Anaconda Python 3.6对MinGW的版本比较挑剔,太新或者太旧的版本都容易出问题。建议试试gcc 4.8.x版本的MinGW32,这是当时Anaconda官方推荐的兼容版本,适配性会好很多。
内容的提问来源于stack exchange,提问作者Ben

