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