使用 mingw-w64 编译 mex 的链接器错误
Posted
技术标签:
【中文标题】使用 mingw-w64 编译 mex 的链接器错误【英文标题】:Linker error compiling mex with mingw-w64 【发布时间】:2014-07-17 16:52:11 【问题描述】:我正在尝试将 Mingw-w64 设置为 MATLAB 2013a 中的 mex 编译器。我的笔记本电脑具有 x86_64 架构并运行 Windows 7。我要编译的程序使用 c++11 风格的线程,所以我使用 mingw-w64 版本 4.9.0 和 posix 线程。
根据我找到的here 和here 的说明,我修改了我的mexopts.bat 文件。代码似乎编译成功,但是链接器报错。有没有人建议我可能做错了什么?
顺便说一句,我尝试使用 gnumex 来设置编译器,但也没有用。
这是 MATLAB 给出的输出和错误消息:
>mex -v Gomoku_mex.cpp
-> Default options filename found in C:\Users\Bas\AppData\Roaming\MathWorks\MATLAB\R2013a
-> Options file = C:\Users\Bas\AppData\Roaming\MathWorks\MATLAB\R2013a\mexopts.bat
MATLAB = C:\Program Files\MATLAB\R2013a
-> COMPILER = x86_64-w64-mingw32-g++
-> Compiler flags:
COMPFLAGS = -std=c++11 -fexceptions -I"C:\Program Files\MATLAB\R2013a\extern\include"
OPTIMFLAGS = -O3 -fexpensive-optimizations -DNDEBUG
DEBUGFLAGS = -g -Wall -Wextra
arguments =
Name switch = -o
-> Pre-linking commands=
-> LINKER = x86_64-w64-mingw32-g++
-> Link directives:
LINKFLAGS = -shared mex.def -L"C:\Program Files\MATLAB\R2013a\bin\win64" -static-libstdc++
LINKDEBUGFLAGS = -g -Wall
LINKFLAGSPOST = -lmex -lmx -lmat -lmwlapack -lmwblas
Name directive = -o "Gomoku_mex.mexw64"
File link directive =
Lib. link directive =
Rsp file indicator =
-> Resource Compiler =
-> Resource Linker =
----------------------------------------------------------------
--> x86_64-w64-mingw32-g++ -std=c++11 -fexceptions -I"C:\Program Files\MATLAB\R2013a\extern\include" -oC:\Users\Bas\AppData\Local\Temp\mex_r7jRw0\Gomoku_mex.obj -I"C:\Program Files\MATLAB\R2013a\extern\include" -I"C:\Program Files\MATLAB\R2013a\simulink\include" -O3 -fexpensive-optimizations -DNDEBUG -DMX_COMPAT_32 Gomoku_mex.cpp
C:\Users\Bas\AppData\Local\Temp\cc4hwD3A.o:Gomoku_mex.cpp:(.text+0x9d1c): undefined reference to `mxGetPr'
C:\Users\Bas\AppData\Local\Temp\cc4hwD3A.o:Gomoku_mex.cpp:(.text+0x9d83): undefined reference to `mxCreateDoubleScalar'
C:/PROGRA~1/mingw-w64/x86_64-4.9.0-posix-seh-rt_v3-rev2/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.9.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\Bas\AppData\Local\Temp\cc4hwD3A.o: bad reloc address 0x0 in section `.pdata$_ZNKSt5ctypeIcE8do_widenEc'
collect2.exe: error: ld returned 1 exit status
C:\PROGRA~1\MATLAB\R2013A\BIN\MEX.PL: Error: Compile of 'Gomoku_mex.cpp' failed.
Error using mex (line 206)
Unable to complete successfully.
编辑:作为额外信息,这是我的 mexopts.bat 文件。我直接从上面的两个链接之一得到了这个,修改了目录和编译器名称并添加了 -std=c++11
set MATLAB=%MATLAB%
set PATH=%PATH%;C:\PROGRA~1\mingw-w64\x86_64-4.9.0-posix-seh-rt_v3-rev2\mingw64\bin
set MW_TARGET_ARCH=win64
rem ********************************************************************
rem Compiler parameters
rem ********************************************************************
set COMPILER=x86_64-w64-mingw32-g++
set COMPFLAGS=-std=c++11 -fexceptions -I"%MATLAB%\extern\include"
set OPTIMFLAGS=-O3 -fexpensive-optimizations -DNDEBUG
set DEBUGFLAGS=-g -Wall -Wextra
set NAME_OBJECT=-o
rem ********************************************************************
rem Linker parameters
rem ********************************************************************
set PRELINK_CMDS1=echo EXPORTS > mex.def & echo mexFunction >> mex.def
set LINKER=x86_64-w64-mingw32-g++
set LINKFLAGS= -static-libstdc++ -shared mex.def -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft"
set LINKFLAGSPOST= -lmex -lmx -lmat -lmwlapack -lmwblas
set LINKOPTIMFLAGS=-O3
set LINKDEBUGFLAGS= -g -Wall
set LINK_FILE=
set LINK_LIB=
set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
set RSP_FILE_INDICATOR=
set POSTLINK_CMDS1=del mex.def
【问题讨论】:
发布您正在使用的版本(mexopts
文件)以及您所做的修改
【参考方案1】:
获取我正在使用的以下配置文件(您需要相应地调整指向 MinGW-w64 位置的路径):
mingw_mexopts.bat
@echo off
set MATLAB=%MATLAB%
set MW_TARGET_ARCH=win64
set PATH=C:\MinGW-w64\mingw64\bin;%PATH%
set COMPILER=x86_64-w64-mingw32-g++
set COMPFLAGS=-c -m64 -mwin32 -mdll -Wall -std=c++11 -DMATLAB_MEX_FILE
set OPTIMFLAGS=-DNDEBUG -O2
set DEBUGFLAGS=-g
set NAME_OBJECT=-o
set LINKER=x86_64-w64-mingw32-g++
set LINKFLAGS=-shared -L"%MATLAB%\extern\lib\win64\microsoft" -L"%MATLAB%\bin\win64"
set LINKFLAGSPOST=-lmx -lmex -lmat
set LINKOPTIMFLAGS=-O2
set LINKDEBUGFLAGS=-g
set LINK_FILE=
set LINK_LIB=
set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
接下来是一个使用 C++11 线程的简单 MEX 函数:
test.cpp
#include "mex.h"
#include <vector>
#include <thread>
void say_hello(int tid)
mexPrintf("hello from %d\n", tid);
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
std::vector<std::thread> threads;
for (int i=0; i<10; i++)
threads.push_back(std::thread(say_hello, i));
for(auto& t : threads)
t.join();
最后我们在 MATLAB 中编译并运行它:
>> mex -f mingw_mexopts.bat -largeArrayDims test.cpp
>> setenv('PATH', ['C:\MinGW-w64\mingw64\bin;', getenv('PATH')])
>> test
hello from 0
hello from 4
hello from 2
hello from 3
hello from 5
hello from 1
hello from 6
hello from 8
hello from 7
hello from 9
请注意,如果您要将其部署到另一台机器上,您还必须复制一些相关的 DLL(您可以在 MinGW bin
文件夹中找到它们),并将它们放在 MEX 旁边-文件。使用Dependency Walker 列出它们。在我的情况下是:
libstdc++-6.dll
libgcc_s_seh-1.dll
libwinpthread-1.dll
我正在使用 GCC 4.8.2 和在 64 位 Windows 上运行的 MATLAB R2014a。
【讨论】:
您的 mexopts.bat 适用于测试文件和我自己的可执行文件。仔细检查后,我发现我缺少 -c 编译器标志。当我将它添加到我的 mexopts.bat 脚本时,它也能正常工作。【参考方案2】:注意这些错误信息:
C:\Users\Bas\AppData\Local\Temp\cc4hwD3A.o:Gomoku_mex.cpp:(.text+0x9d1c): undefined reference to `mxGetPr'
C:\Users\Bas\AppData\Local\Temp\cc4hwD3A.o:Gomoku_mex.cpp:(.text+0x9d83): undefined reference to `mxCreateDoubleScalar'
未在您的链接命令中添加 libmex、libmx、libmat 的库搜索路径。脚本中的目录是包含 DLL 的 bin 目录。这里不正确。
LINKFLAGS = -shared mex.def -L"C:\Program Files\MATLAB\R2013a\extern\lib\win64\microsoft" -static-libstdc++
【讨论】:
谢谢!我更新了 mexopts.bat 文件,现在将 %MATLAB%\extern\lib\win64\microsoft 添加到链接器目录。我检查了这个目录是否包含文件 libmex.lib、libmx.lib 等。不幸的是,它仍然给出了同样的错误。以上是关于使用 mingw-w64 编译 mex 的链接器错误的主要内容,如果未能解决你的问题,请参考以下文章