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函數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM