Python64+win10_64+cython+msys2(ming64)踩坑记

一直在linux下用python,一直妥妥的,从没想过在windows下编译cython模块,直到昨天……

过程是曲折的,解决方法是简单的,时间不多,长话短说,直接先来个传送门:

https://www.jianshu.com/p/50105307dea5

这里的步骤是可以的,因为我用的msys2,所以过程有一点点曲折,下边补充说明一下:

msys2算是个windows下的linux系统,里边一共包含了3套工具链,

比如安装GCC,可以直接安装gcc这个包,也可以安装mingw-w64-i686-gcc或者mingw-w64-x86_64-gcc

这三个包不同之处在于,gcc是属于msys2系统本身的工具链,如果编译软件,会连接到/usr/lib下,也就是虽然生成的是exe,但是是没法离开msys2运行的

而mingw-w64-i686-gcc与mingw-w64-x86_64-gcc实际上是个交叉工具链,编译出来的exe是只依赖宿主系统的库的,所以可以直接在windows系统下运行的

甚至只要吧msys2下的mingw64/bin目录加到系统系统变量,是可以随便调用的。

python配合msys2的使用方式:

python也可以有3种安装方式,

1,直接从python官方下载安装包安装,这是最普遍的做法,跟msys2完全没关系,可以直接通过系统环境变量调用相应的mingw32或者mingw64编译器,编译自己的包

2,在msys2直接安装python,配合msys2的gcc,这样类似直接在linux安装gcc python,最方便,编译连接时也不需要指定路径,类似linux下的体验,缺点是编译生成

的exe文件无法离开msys2运行

3,安装mingw-w64-x86_64-gcc mingw-w64-x86_64-python这种工具链下的包,这个其实跟1类似,可以编译直接在系统下运行的exe,也可以直接在msys2下使用。

因为我系统下已经安装了python3 64bit,并且安装了大量的包,所以装完msys2以后,直接安装mingw-w64-x86_64-gcc就可以在pyhon3中使用这个编译器了。

pacman -S mingw-w64-x86_64-gcc

然后把mingw64加到系统环境变量比如我msys2安装在E:\linux(没错我伪装成linux了哈)下,系统环境变量就加一条E:\linux\mingw64\bin。

根据传送门的教程:在python安装目录C:\Program Files\Python\Lib\distutils中新建distutils.cfg文件,内容如下:

[build]
compiler=mingw32

[build_ext]
compiler=mingw32

注意,这地方是没错的,不要因为是mingw64就写mingw64,写mingw32是对的。

这时候,编译一个cython程序,会报VC版本1900 1906之类,根据教程这么改:

三、修改cygwinccompiler.py文件

进入python安装目录C:\Program Files\Python\Lib\distutils中,修改cygwinccompiler.py文件,添加以下内容到get_msvcr()函数(用于解决ValueError: Unknown MS Compiler version 1900错误)。

elif msc_ver == '1900':
    # Visual Studio 2015 / Visual C++ 14.0
    # "msvcr140.dll no longer exists"
    return ['vcruntime140']

因为我这报的是1906,所以就改成了

elif msc_ver == '1906':
    # Visual Studio 2015 / Visual C++ 14.0
    # "msvcr140.dll no longer exists"
    return ['vcruntime140']

这一步一定要根据实际版本改。

转换python36.dll文件
用于解决C:\Program Files\Python\libs/libpython36.a: error adding symbols: File format not recognized错误。

复制C:\Program Files\Python\python36.dll到桌面,执行以下命令:

gendef python36.dll
dlltool -D python36.dll -d python36.def -l libpython36.a


备份C:\Program Files\Python\libs/libpython36.a文件,将上步生成的libpython36.a复制到C:\Program Files\Python\libs目录下。

转换vcruntime140.dll文件
用于解决C:\Program Files\Python / vcruntime140.dll: file not recognized: File format not recognized错误。

复制C:\Program Files\Python\vcruntime140.dll到桌面,执行以下命令:

gendef vcruntime140.dll
dlltool -D vcruntime140.dll -d vcruntime140.def -l libvcruntime140.a

2.将生成的libvcruntime140.a复制到C:\ProgramFiles\Python\libs目录即可。

这几步没什么问题,我是python3.7.x,所以上边的python36.dll改成python37.dll,当然,我是python装到了D盘,所以对应的C:\Program Files\xxxxx要改成D:

另外,gendef需要安装mingw-w64-x86_64-tools-git

pacman -S mingw-w64-x86_64-tools-git

否则没有这个命令。

另外,在我这编译cython时会出现一些编译错误,经过网上搜索,加了-DMS_WIN64选项,问题全部解决

        self.set_executables(compiler='gcc -O -Wall -DMS_WIN64',
                             compiler_so='gcc -mdll -O -Wall -DMS_WIN64',
                             compiler_cxx='g++ -O -Wall',
                             linker_exe='gcc',
                             linker_so='%s %s %s'
                                        % (self.linker_dll, shared_option,
                                           entry_point))
        # Maybe we should also append -mthreads, but then the finished
        # dlls need another dll (mingwm10.dll see Mingw32 docs)
        # (-mthreads: Support thread-safe exception handling on `Mingw32')

        # no additional libraries needed

 

以上内容在

gcc -v
Using built-in specs.
COLLECT_GCC=E:\linux\mingw64\bin\gcc.exe
COLLECT_LTO_WRAPPER=E:/linux/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../gcc-9.2.0/configure --prefix=/mingw64 --with-local-prefix=/mingw64/local --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --with-native-system-header-dir=/mingw64/x86_64-w64-mingw32/include --libexecdir=/mingw64/lib --enable-bootstrap --with-arch=x86-64 --with-tune=generic --enable-languages=c,lto,c++,fortran,ada,objc,obj-c++ --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-filesystem-ts=yes --enable-libstdcxx-time=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --disable-isl-version-check --enable-lto --enable-libgomp --disable-multilib --enable-checking=release --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --enable-plugin --with-libiconv --with-system-zlib --with-gmp=/mingw64 --with-mpfr=/mingw64 --with-mpc=/mingw64 --with-isl=/mingw64 --with-pkgversion='Rev1, Built by MSYS2 project' --with-bugurl=https://sourceforge.net/projects/msys2 --with-gnu-as --with-gnu-ld
Thread model: posix
gcc version 9.2.0 (Rev1, Built by MSYS2 project)

python 3.7.3/3.7.4环境下通过

另外,cython还支持把python文件编译成一个独立的exe文件, 也需要加两个特殊的选项:

cython --embed fibonacci.py

gcc fibonacci.c "-ID:\\Program Files\\Python37\\include\\" "-LD:\\Program Files\\Python37\\libs" -lpython37 -municode -DMS_WIN64 -o fib.exe

比平时多加了-municode -DMS_WIN64两个选项,其中第一个选项的作用是使用wmain这个函数作为main函数。

posted on 2019-08-26 15:56  yafeng  阅读(6835)  评论(0编辑  收藏  举报

导航