1. gcc的-M類型參數問題。

  2. math.h與pyconfig.h衝突修正。

  3. 使用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的文件時,同時導入cmathPython.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