【问题标题】:How to link to third party dll when cross compiling from linux?从linux交叉编译时如何链接到第三方dll?
【发布时间】:2017-01-21 04:24:39
【问题描述】:

我想使用 mingw-w64 工具从 Linux 交叉编译适用于 Windows 64 位的 C++ 项目(实际上我使用的是基于 mingw-w64 的 M Cross Environment,但我认为这与题)。在我的情况下,最后一步需要链接到几个第三方编译的 dll。我没有这些dll的源代码,只有头文件和编译好的二进制文件 用什么编译?我不知道,但可能是 Visual Studio。

为了准确解释我在做什么,我想从 Linux 交叉编译 Matlab mex 文件,并且需要链接到 Matlab 库 libmex.dll、libmx.dll 和 libmat.dll。但是,我认为回答这个问题不需要任何 Matlab 知识。

我隐约意识到我需要从 dll 中提取定义到 .def 文件中,也许我需要创建另一个链接库来实际链接到。

我已经尝试了这两个步骤,首先是为每个库创建定义文件,我使用以下命令:

gendef libmx.dll

这是生成的定义文件libmx.def的sn-p

;
; 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

然后我尝试根据为 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++ 构建过程混淆有关的任何明显缺陷!

【问题讨论】:

    标签: c++ linker cross-compiling mingw-w64 mxe


    【解决方案1】:

    你确定你转换成静态库的三个库不依赖于windows没有提供的其他dll(你可以用dep walker,http://www.dependencywalker.com/,在wine中查看)?

    我也想交叉编译 mex 文件,但我找不到可以在 linux 中完全运行的解决方案。

    所以我所做的就是将我的项目交叉编译为单个独立的 dll,最后使用 matlab 中的 mex 并在 dll 上链接来编译 windows 上 mex 文件的“主”文件。

    如果你没有windows电脑,也许你可以尝试在wine中安装matlab和mingw。

    【讨论】:

    • 谢谢,最后我确实找到了解决方案,最近的 matlab 版本支持 windows 上的 mingw,并附带了适当的库,您可以在交叉编译时链接到这些库。请注意,这仍然是一个痛苦的过程,而且他们正在改变编译器的设置方式,因此无论您设置什么系统都可能停止工作。我现在只有一个 Windows VM,并且正在考虑使用 buildbot 将其自动化。不过,我会尝试调查您的答案,但可能需要一段时间。
    猜你喜欢
    • 2022-06-12
    • 1970-01-01
    • 2014-01-16
    • 2017-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 2021-04-29
    相关资源
    最近更新 更多