crobar
crobar

Reputation: 2939

How to link to third party dll when cross compiling from linux?

I would like to cross compile C++ projects for Windows 64 bit from Linux using the mingw-w64 tools (Actually I am using M Cross Environment which is based on mingw-w64, but I don't think this is relevant to the question). In my case the final step requires linking to several third party compiled dlls. I do not have the source code of these dlls, only the header files and compiled binary Compiled using what? I do not know but likely Visual Studio.

To explain exactly what I am doing, I want to cross-compile Matlab mex files from Linux and need to link to the Matlab libraries libmex.dll, libmx.dll and libmat.dll. However, I don't think any Matlab knowledge is required to answer the question.

I am vaguely aware that I need to extract definitions from the dlls, into .def files, and maybe that I need to create another link library of some kind to actually link to.

I have attempted both of these steps, first the creation of definition files for each library, which I did with the following command:

gendef libmx.dll

Here's a snippet of the resulting definition file 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 
??0?$Mprotected_cptr@UmxArray_tag@@VMprotected_mxArray_helper@@@@QEAA@AEBV0@@Z
; public: __cdecl <struct mxArray_tag,class Mprotected_mxArray_helper>::<struct mxArray_tag,class Mprotected_mxArray_helper>(struct mxArray_tag *__ptr64,bool)__ptr64 
??0?$Mprotected_cptr@UmxArray_tag@@VMprotected_mxArray_helper@@@@QEAA@PEAUmxArray_tag@@_N@Z
; public: __cdecl <struct mxArray_tag,class Mprotected_mxArray_helper>::<struct mxArray_tag,class Mprotected_mxArray_helper>(void)__ptr64 
??0?$Mprotected_cptr@UmxArray_tag@@VMprotected_mxArray_helper@@@@QEAA@XZ
; public: __cdecl matrix::serialize::Exception::Exception(class matrix::serialize::Exception const &__ptr64 )__ptr64 
??0Exception@serialize@matrix@@QEAA@AEBV012@@Z
; public: __cdecl matrix::serialize::Exception::Exception(int,__int64)__ptr64 
??0Exception@serialize@matrix@@QEAA@H_J@Z
; public: __cdecl matrix::serialize::FailedUCNV::FailedUCNV(class matrix::serialize::FailedUCNV const &__ptr64 )__ptr64 
??0FailedUCNV@serialize@matrix@@QEAA@AEBV012@@Z
; public: __cdecl matrix::serialize::FailedUCNV::FailedUCNV(int,__int64,int)__ptr64 
??0FailedUCNV@serialize@matrix@@QEAA@H_JH@Z
; public: __cdecl Mprotected_mxArray::Mprotected_mxArray(class Mprotected_mxArray const &__ptr64 )__ptr64 
??0Mprotected_mxArray@@QEAA@AEBV0@@Z
; public: __cdecl Mprotected_mxArray::Mprotected_mxArray(struct mxArray_tag *__ptr64,bool)__ptr64 
??0Mprotected_mxArray@@QEAA@PEAUmxArray_tag@@_N@Z
; public: __cdecl Mprotected_mxArray::Mprotected_mxArray(void)__ptr64 
??0Mprotected_mxArray@@QEAA@XZ
; public: __cdecl RRTableVisitor::RRTableVisitor(class RRTableVisitor const &__ptr64 )__ptr64 
??0RRTableVisitor@@QEAA@AEBV0@@Z

I then attempted to create an import library based on the instructions provided for Mingw here. However, as I am using mingw-w64 my command was actually

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

However, when I attempt to build a simple example linked to these libraries, I get an error. Here is the actual commands used to build and link the libs.

/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++

The compile step goes ok, but the linking step fails with the following error:

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

I am happy for the result of this compilation to be statically linked.

So my question is, what exactly do I have to do to link to third party dlls when cross-compiling for Windows from Linux, and why might the linking step be failing in this case?

By the way, this particular example is for a simple C file example, in reality I will also want to link C++ files. Feel free to point out any obvious flaws in my process related to being confused about C and C++ build processes!

Upvotes: 4

Views: 1466

Answers (1)

Laurent Jospin
Laurent Jospin

Reputation: 614

Are you sure the three libraries you transformed into static libs do not depend of other dlls that are not provided with windows (you can look at it with dep walker, http://www.dependencywalker.com/, in wine) ?

I also wanted to cross compile mex files, but I wasn't able to find a solution that would work completly in linux.

So what I did is to cross compile my project as a single, independant, dll and finally to compile the "main" of the mex file on windows using mex from matlab and linking on the dll.

If you don't have acess to a windows computer, maybe you can try to install matlab and mingw in wine.

Upvotes: 0

Related Questions