-
gcc的
-M
類型參數問題。 -
math.h與pyconfig.h衝突修正。
-
使用libpython35.a解決_wrap.cxx找不到函式的問題。
Solvespace Makefile :
目前發現obj檔案無法辨識的原因是原始Makefile中加上了-MT
這個參數,然而沒有這個參數,只能改用-MD
來取代。
直到Link這些obj檔時才發現,這些obj檔竟然是文字文件,而另一個Makefile導出的obj檔都相當正常。
最後決定把Makefile中gcc的參數統一化,剩下才發現-M
系的參數會輸出信息檔,而不是物件。
但是將obj檔重新連結成solvespace.exe
時就開始顯示大大小小的錯誤了,而且並非-W
的普通警告。相反的另一邊exposed資料夾就沒出現過警告。
所以要成功編譯就必須將錯誤修正,看一些關於C++的資料。這些錯誤貌似都是物件繼承、指標項的用法問題。
不過今天專注在如何克服exposed資料夾的錯誤。
MinGW的math.h和Python的pyconfig.h :
上網搜尋了許多文章,大部分的人使用MinGW編譯C轉Python的文件時,同時導入cmath
和Python.h
都會遇到這個衝突。
主要原因是<math.h>中有一段_hypot(double _X, double _Y)
的函式,而它的名稱剛好與pyconfig.h
中的define hypot _hypot
衝突。
上網搜尋時找到一系列2013年的信件:
http://www.vtk.org/pipermail/vtk-developers/2013-March/013475.html
主要是討論如何處理這個問題,信中曾建議在自己的程式碼的include <Python.h>
下加上這段:
#include <cmath> #include <Python.h> #ifdef hypot #undef hypot #endif
但是這樣根本不可行,因為導入Python.h
時就會同時導入pyconfig.h
,一旦導入pyconfig.h
就會產生衝突,後面再undefine也不會有用。
所以根本的問題就是修改pyconfig.h
,變成這一段:
#ifndef _MATH_H_ #define hypot _hypot #endif
讓它只能在沒有math.h
的時候才能使用。
更改後編譯就沒有問題了。
不過不知道這樣更改會不會讓Anaconda的Python衍生其他狀況。
libpython35.a :
出現了slvs_wrap.cxx
匯入函式的問題。
slvs_wrap.o: In function `_SWIG_Py_None': slvs_wrap.cxx:1446: undefined reference to `__imp__Py_RefTotal' ...
這些是SWIG自動產生的,interface無法修改。
上網搜尋了一下,應該是軟體位元問題,找到了類似的問題。
http://www.gdomc.com/0423/how-can-i-build-my-c-extensions-with-mingw-w64-in-python/
接著參考另一篇文章生成libpython35.a
。
https://github.com/kivy/kivy/wiki/Creating-a-64-bit-development-environment-with-MinGW-on-Windows
首先,將Python的DLL檔複製一份進Python的libs資料夾中。
接著下載gendef.exe
,它也是MinGW的工具之一,從下列網址下載gendef-1.0.1346-1-mingw32-bin.tar.lzma
:
https://sourceforge.net/projects/mingw/files/MinGW/Extension/gendef/gendef-1.0.1346/
解壓縮進MinGW的bin資料夾中。
接著用CMD進入Python的libs資料夾中使用以下命令。
gendef python35.dll dlltool --dllname python35.dll --def python35.def --output libpython35.a
dlltool
是GNU內建的工具,有安裝過安裝版的GNU工具包就能在本機端環境使用。
做完後就會產生libpython35.a
這個檔案。
然後到Python的include資料夾開啟pyconfig.h
這個檔案編輯。
搜尋並將以下內容剪下:
#ifdef _WIN64 #define MS_WIN64 #endif
貼到以下內容的「上方」:
#ifdef _MSC_VER ...
再到Python的Lib\distutils
資料夾中,開啟cygwinccompiler.py
這個檔案。
搜尋以下內容並註解掉:
self.dll_libraries = get_msvcr()
注意四周會有相似的內容,不要弄錯註解。
範例在編譯slvs_wrap.o
時加上-DMS_WIN64
參數。
不過這時因為已經修改過pyconfig.h
的內容,會自動宣告MS_WIN64
,所以加上會提示說重複宣告。
最後編譯用的指令如下。
g++ -IW:/Anaconda3/include -Wno-unused-but-set-variable -c -o ../obj/slvs_wrap.o slvs_wrap.cxx g++ -shared -fPIC -o _slvs.so ... ../extlib/si/siapp.lib -LW:/Anaconda3/libs -lPython35
但是最後還是出現一點錯誤:
應該是內部的導入問題。
由於時間不多,所以這個部分之後再解決。
今天有稍微比較下Whitequark的原始碼,不過用法已經完全不一樣,相同的變數也改變了型態,更有系統性,但是也更難判讀,所以.cpp
的部分還得熟悉相關的知識。
Solvespace Makefile的部分是編譯solvespace.exe
的部分,不過Python呼叫的部分應該是不用那麼多,畢竟那些大部分都是介面檔,真正的本體只需要判斷是否衝突。
所以Solvespace Makefile的部分才做得漫不經心吧。
exposed Makefile部分的all
為三個目標:
all: cdemo _slvs.so slvs.py LD_LIBRARY_PATH=. ./cdemo
CDemo的部分已經成功轉出可執行檔;_slvs.so
還在最後階段的編譯中;slvs.py
則是原作者撰寫好的(不過是Python 2)。
預計不久後就能夠測試_slvs.so
的功能。
Comments
comments powered by Disqus