2016-09-13 79 views
1

我想越過使用mingw-w64工具從Linux的編譯對於Windows 64位C++項目(其實我使用的是基於MinGW的-W64 M Cross Environment,但我不認爲這是相關的問題)。在我的情況下,最後一步需要鏈接到幾個第三方編譯的dll。我沒有這些DLL的源代碼,只有頭文件和編譯後的二進制文件使用什麼編譯?我不知道,但可能Visual Studio。如何從linux交叉編譯時鏈接到第三方DLL?

要解釋清楚我在做什麼,我想從Linux的交叉編譯Matlab的MEX文件,需要鏈接到Matlab的庫libmex.dll,libmx.dll和libmat.dll。但是,我不認爲需要任何Matlab知識來回答這個問題。

我隱約地感到自己需要從動態鏈接庫中提取的定義,到.DEF文件,這也許就是我需要建立某種實際鏈接到另一個鏈接庫。

我已嘗試這兩個步驟,第一個創建的定義文件對每個庫,我用下面的命令做了:

gendef libmx.dll 

這裏是造成定義文件的片斷libmx.def

; 
; Definition file of libmx.dll 
; Automatic generated by gendef 
; written by Kai Tietz 2008 
; 
LIBRARY "libmx.dll" 
EXPORTS 
; public: __cdecl <struct mxArray_tag,class Mprotected_mxArray_helper>::<struct mxArray_tag,class Mprotected_mxArray_helper>(class <struct mxArray_tag,class Mprotected_mxArray_helper> const &__ptr64)__ptr64 
[email protected][email protected]@[email protected]@@@[email protected]@@Z 
; public: __cdecl <struct mxArray_tag,class Mprotected_mxArray_helper>::<struct mxArray_tag,class Mprotected_mxArray_helper>(struct mxArray_tag *__ptr64,bool)__ptr64 
[email protected][email protected]@[email protected]@@@[email protected][email protected]@[email protected] 
; public: __cdecl <struct mxArray_tag,class Mprotected_mxArray_helper>::<struct mxArray_tag,class Mprotected_mxArray_helper>(void)__ptr64 
[email protected][email protected]@[email protected]@@@[email protected] 
; public: __cdecl matrix::serialize::Exception::Exception(class matrix::serialize::Exception const &__ptr64)__ptr64 
[email protected]@[email protected]@[email protected]@@Z 
; public: __cdecl matrix::serialize::Exception::Exception(int,__int64)__ptr64 
[email protected]@[email protected]@[email protected][email protected] 
; public: __cdecl matrix::serialize::FailedUCNV::FailedUCNV(class matrix::serialize::FailedUCNV const &__ptr64)__ptr64 
[email protected]@[email protected]@[email protected]@@Z 
; public: __cdecl matrix::serialize::FailedUCNV::FailedUCNV(int,__int64,int)__ptr64 
[email protected]@[email protected]@[email protected][email protected] 
; public: __cdecl Mprotected_mxArray::Mprotected_mxArray(class Mprotected_mxArray const &__ptr64)__ptr64 
[email protected]@[email protected]@@Z 
; public: __cdecl Mprotected_mxArray::Mprotected_mxArray(struct mxArray_tag *__ptr64,bool)__ptr64 
[email protected]@[email protected][email protected]@[email protected] 
; public: __cdecl Mprotected_mxArray::Mprotected_mxArray(void)__ptr64 
[email protected]@[email protected] 
; public: __cdecl RRTableVisitor::RRTableVisitor(class RRTableVisitor const &__ptr64)__ptr64 
[email protected]@[email protected]@@Z 

然後,我試圖根據Mingw here提供的說明創建導入庫。然而,由於我使用的MinGW-W64我的命令竟是

x86_64-w64-mingw32.static-dlltool -d libmx.def -l libmx.a 

然而,當我試圖建立連接到這些庫一個簡單的例子,我得到一個錯誤。以下是用於構建和鏈接庫的實際命令。

/opt/mxe/usr/bin/x86_64-w64-mingw32.static-gcc -c -I/usr/local/MATLAB/R2015a/extern/include -I/usr/local/MATLAB/R2015a/simulink/include -DMATLAB_MEX_FILE -std=c99 -D_GNU_SOURCE -fexceptions -fPIC -fno-omit-frame-pointer -pthread -I/opt/mxe/usr/bin/include -DMX_COMPAT_32 -O -DNDEBUG "/home/rcrozier/yprime.c" 
/opt/mxe/usr/bin/x86_64-w64-mingw32.static-gcc -O -L/home/rcrozier/Sync/work/matlab_windows_libs/r2013a -L/opt/mxe/usr/bin/lib -pthread -Wl,--version-script,/usr/local/MATLAB/R2015a/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined -I/usr/local/MATLAB/R2015a/extern/include -o "yprime.mexw64" yprime.o -Wl,-rpath-link -L/home/rcrozier/Sync/work/matlab_windows_libs/r2013a -lmx -lmex -lmat -L/opt/mxe/usr/bin/lib -lm -lstdc++ 

編譯步驟去確定,但鏈接步驟失敗,出現以下錯誤:

yprime.o:yprime.c:(.text+0x53): undefined reference to `mxGetM' 
yprime.o:yprime.c:(.text+0x5f): undefined reference to `mxGetN' 
yprime.o:yprime.c:(.text+0x6b): undefined reference to `mxIsDouble' 
yprime.o:yprime.c:(.text+0x78): undefined reference to `mxIsComplex' 
yprime.o:yprime.c:(.text+0xbe): undefined reference to `mxCreateDoubleMatrix_700' 
yprime.o:yprime.c:(.text+0xca): undefined reference to `mxGetPr' 
yprime.o:yprime.c:(.text+0xd5): undefined reference to `mxGetPr' 
yprime.o:yprime.c:(.text+0xde): undefined reference to `mxGetPr' 
/opt/mxe/usr/lib/gcc/x86_64-w64-mingw32.static/4.9.4/../../../../x86_64-w64-mingw32.static/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o): In function `main': 
/opt/mxe/tmp-gcc-x86_64-w64-mingw32.static/gcc-4.9.4/mingw-w64-v4.0.6/mingw-w64-crt/crt/crt0_c.c:18: undefined reference to `WinMain' 
collect2: error: ld returned 1 exit status 

我很高興此編譯的結果靜態鏈接。

所以我的問題是,究竟是什麼我必須做在Linux當交叉編譯的Windows鏈接到第三方的DLL,爲什麼會連接步驟是在這種情況下失敗?

順便說一句,這個特定的例子是一個簡單的C文件的例子,實際上我也想鏈接C++文件。隨意指出我的流程中涉及到對C和C++構建流程感到困惑的任何明顯缺陷!

回答

0

你確定你轉換成靜態庫的三個庫不依賴於其他沒有提供的窗口的dll(你可以用dep walker來查看,http://www.dependencywalker.com/,在wine中)?

我也想交叉編譯MEX文件,但我沒能找到一個解決方案,在Linux完全地工作。

因此,我所做的就是將我的項目作爲單獨的獨立的dll進行交叉編譯,最後使用來自matlab的mex和dll上的鏈接來編譯windows上mex文件的「主」。

如果你沒有接入Windows電腦,也許你可以嘗試安裝matlab和mingw葡萄酒。

+0

謝謝,最終我找到了一個解決方案,最近的matlab版本在windows上支持mingw,並帶有相應的庫,您可以在交叉編譯時鏈接到相應的庫。對你來說,這仍然是一個痛苦的過程,他們正在改變編譯器的設置方式,所以你設置的任何系統都可能停止工作。我只是建立了一個Windows虛擬機,現在想建立一個Windows虛擬機,想用[buildbot](https://buildbot.net)自動化它。儘管我會盡力調查你的答案,但這可能需要一段時間。 – crobar

相關問題