使用GCC(MinGW)作为MATLAB的MEX编译器
我已经有了一个在MATLAB R2011a上运行的项目。 由于这里有几个.c文件,我需要将GCC设置为该项目的MEX编译器。 但是,我似乎无法find任何解释如何设置它。 我试过了一个名为gnumex的脚本程序 – 但是它失败了(可能是为MATLAB的老版本设置的)。
任何想法如何设置?
在Matlab 2011b中,直接在mingw64或者cygwin环境下编译链接即可。
MINGWPATH=c:/MinGW64 CYGPATH=c:/cygwin MATLABROOT=c:/Progra~1/MATLAB/R2011b CC=$(MINGWPATH)/bin/x86_64-w64-mingw32-gcc CFLAG= -Wall -m64 -O3 -I$(MATLABROOT)/extern/include $(SRC) $(LIBS) -o $(EXE) MEXFLAG=-m64 -shared -DMATLAB_MEX_FILE -I$(MATLABROOT)/extern/include -Wl,--export-all-symbols $(LIBS) $(MEXSRC) -o $(MEXTGT).mexw64 LIBS= -L$(MATLABROOT)/bin/win64 -L$(MATLABROOT)/extern/lib/win64/microsoft -lmex -lmx -lmwlapack -lmwblas -leng EXE=../bin/engwindemo.exe MEXTGT= SRC=engwindemo.c MEXSRC= all:$(EXE) $(EXE): $(SRC) $(CC) $(CFLAG) -ladvapi32 -luser32 -lgdi32 -lkernel32 -lmingwex -o $(EXE) @rm -f *.o* $(MEXTGT): $(MEXSRC) $(CC) $(MEXFLAG) -ladvapi32 -luser32 -lgdi32 -lkernel32 -lmingwex @rm -f *.o*
把这个makefile放在源代码目录下并make
。 没有dll文件转换需要。
为什么不调整目录中的mexopts.bat文件? 这样,你可以像在平时一样使用“mex”命令来透明地编译任何东西,就像使用mex -setup
的MATLABconfiguration一样。 我很惊讶之前没有人这样做。
下面的文件是Matlab和Mingw的x64版本。 我使用的是TDM Mingw64发行版,我安装在p:\mingw64-tdm
。 我有Matlab安装在p:\matlab\R2012a
– 编辑相应的。
这是我正在使用的mexopts.bat文件,将其粘贴到%USERPROFILE%\AppData\Roaming\MathWorks\MATLAB\R2012a\mexopts.bat
:
@echo off set MINGWPATH=p:\mingw64-tdm set PATH=%MINGWPATH%\bin;%PATH% set COMPILER=gcc set COMPFLAGS=-c -m64 -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE -Wall -std=c99 set OPTIMFLAGS=-O3 -DNDEBUG set DEBUGFLAGS=-g set NAME_OBJECT=-o set LINKER=gcc set LINKFLAGS=-shared -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
那么你可以尝试在Matlab中做这个:
mex -vp:\matlab\R2012a\extern\examples\mex\yprime.c which yprime
应该产生b:\code\m\yprime.mexw64
(或任何当前文件夹)。 那么如果你这样做:
yprime(1,1:4)
你应该看到:
ans = 2.0000 8.9685 4.0000 -1.0947
这意味着你在做生意。 祝你好运!
编辑2014年10月:我现在使用改进的mexopts.bat文件比以上与不同的MinGW64(产生比TDM稍快的二进制代码)。 有关详情和下载,请参阅我的主页 。
从MATLAB R2015b开始,MinGW正式被支持!
它现在在支持的编译器列表的顶部。
请看这里的官方说明下载MinGW(他们推荐TDB-GCC)。
列出了一些限制和注意事项 (例如,不要与其他编译器编译的库链接,必须在MEX文件中捕获exception等)。
以下是我制作XML文件做同样的事情的旧方法。
几年过去了, MATLAB(自R2014a起)已经转移到一个新的基于XML的系统来configurationMEX文件。 现在,MATLAB仍然暂时支持传统的.bat文件,但它会打扰你 。 另一个变化是独特的C和C ++configuration(稍后)。
保持不变的是,你只需要下载并提取一个MinGW分布,并将MATLAB指向它。 仍然不需要MSYS,cygwin或gnumex。 唯一棘手的部分是将MATLAB指向它,但这里是一个解决scheme。
短版
- 下载并提取一个MinGW发行版。 select一个,如MinGW-w64 (64位)或TDM-GCC (32位和64位选项)。
- 自定义XMLconfiguration文件,使用这个作为模板(详细信息见下面的长版本)。
- 设置
MINGWROOT
环境variables。 - 运行
mex -setup:[xmlfile] [C|C++]
。
长版本
对于MinGW-w64,我做了以下设置:
- 从Sourceforge获取w64的最新版本 (或使用安装程序select所需的工具链,根据需要selectpthread或Win32线程版本)。
- 解压缩它,以便获得编译器的path,例如
C:\mingw-w64\x86_64-4.9.2-release-posix-seh-rt_v3-rev1\bin\x86_64-w64-mingw32-g++.exe
。 如果您计划在MATLAB中使用mex
命令编译,则不需要MSYS,cygwin或任何其他环境 。 检查你的PATH
环境variables,确保你的path上没有多个编译器(g++
),最好没有。 用新的命令提示符进行validation。 - 使用自定义的XMLconfiguration文件进行设置。 在我的GitHub仓库中,我发布了两种文件types的MinGW-w64的C ++configuration: mex_C ++ _ mingw-w64.xml和mingw_mexopts.bat 。 从那开始作为一个模板,并且(可选地)用描述性的名字和你下载并提取的MinGW发布版本来编辑XML文件 。
- 设置(或创build)
MINGWROOT
环境variables。 这就是允许mex
命令find编译器的原因。 你可以在MATLAB中使用setenv
来完成这个任务( 每次 MATLAB在userpath
以startup.m
脚本开始),或者使用Windows属性对话框或本机Windows 7的setx.exe命令执行一次 。 -
运行
mex -setup:C:\actual\configFilePath.xml C++
。 例如,使用.xml文件设置C ++ MEX文件编译:setenv('MINGWROOT','H:\mingw-w64\x86_64-4.9.2-release-posix-seh-rt_v3-rev1') mex -setup:H:\building\GitHub\MATLAB\MinGW\mex_C++_mingw-w64.xml C++
输出应该是这样的:
MEXconfiguration为使用'MinGW-w64 GCC 4.9.2 posixthreads seh'进行C ++语言编译。
如果需要的话,以类似的方式设置C编译器,使用指定C语言的新XMLconfiguration文件,C编译器前端(例如“x86_64-w64-mingw32-gcc.exe”,它不会自动链接C ++标准库),根据需要调整链接库,编译器标志(例如,更改-std=c++11
到-std=c99
)等
请注意运行时库的静态链接和dynamic链接
如上面用MinGW-w64创build的MEX文件等库可能依赖于几个DLL(在运行时):LIBGCC_S_SEH-1.DLL(用于sehexception分发)和LIBSTDC ++ – 6.DLL,可能还有libwinpthread-1.dll如果您select一个pthreads分发而不是Win32线程。 如果您不想复制这些文件,可以通过添加以下开关将运行时库静态链接到MEX文件中:
-static-libgcc -static-libstdc++
在XML模板中有一个关于这个的评论。 有关libpthread-1.dll的信息,请参阅此处 。
对于TDM-GCC,情况正好相反 :运行时(包括pthread)是自动静态链接的。 要dynamic链接,这将需要DLL,但减less您的MEX文件大小,您需要:
-shared-libgcc -shared-libstdc++
编辑:似乎有更好的方法与MinGW; 看到我的其他答案。
如果你已经安装了Matlab
,你可以使用gcc
编译.mex
文件。 有人可能会说这是第一次有点乏味。
首先要做的是 – 你用什么Matlab? 如果是64位, MinGW
不会帮你,因为它是32位的。 因此,我将演示如何使用MinGW-w64 。 了解如何用32位MinGW
做到这一点应该很简单。
- 将
C:\MinGW-64\bin\
到您的path。 你不会后悔的:) -
使用
gcc
编译你的.c
文件:x86_64-w64-mingw32-c++ -m64 -shared -I"C:\Program Files\MATLAB\R2010b\extern\include" -o bla.mexw64 -DMATLAB_MEX_FILE -Wl,--export-all-symbols *.cpp
-
这将导致一堆链接器错误,如
undefined reference to `mexErrMsgTxt'
为了解决这个问题,你必须创build一个连接
libmex.dll
,libmx.dll
,libmat.dll
和libeng.dll
的导入库(你可能有其他的,但是这些是主要的) -
列出你错过的function,好吧,猜猜他们是从哪里来的。 提示:
mexErrMsgTxt
来自libmex.dll
,因为它以“mex”开头。 -
对于每个你需要导出的
dll
,创build一个.def
文件包含EXPORTS ... relevant function names go here, such as mexErrMsgTxt, matOpen, etc.
-
执行以下命令来创build导入库:
x86_64-w64-mingw32-dlltool -d libmx.def --dllname libmx.dll -l libmx.a
(与
.def
文件的其余部分相同) -
现在你很好走!
x86_64-w64-mingw32-c++ -m64 -shared -I"C:\..." -DMATLAB_MEX_FILE -o bla.mexw64 -Wl,--export-all-symbols *.cpp libmex.a libmx.a libmat.a libeng.a
事情可以做得更好 – 而不是--export-all-symbol
出口,只导出mexFunction
(需要创build另一个.def
文件,或在void mexFunction(...)
之前添加“ __declspec(dllexport)
”)。
MinGW
能够直接链接一个DLL
; 也就是说,它会在链接时dynamic创build一种导入库。
这意味着编译可以在一个步骤中执行:
x86_64-w64-mingw32-c++ -m64 -shared -I"%MATLAB%/extern/include" -DMATLAB_MEX_FILE -o bla.mexw64 -Wl,--export-all-symbols *.cpp -L"%MATLAB%/bin/win64" -lmex -lmx -leng -lmat
Matlab使用MEX文件链接到外部代码(C ++,Fortran,Java等)。 ( http://gnumex.sourceforge.net/ )
设置编译器:
- 从http://tdm-gcc.tdragon.net/download安装;TDM-GCC (C ++编译器
"C:\MinGW32\bin;"
) - 从( http://ptolemy.eecs.berkeley.edu/ptolemyII/ptII4.0/cygwin.htm )安装Cygwin (工具包在Windows平台上提供Unix工具)。
下载并安装cygwingDevel.exe
- 通过( https://sourceforge.net/projects/gnumex )获取gnumex存档并将gnumex提取到(
$MATLABHOME\gnumex
)。
例如$MATLABHOME
(C:\Program Files\MATLAB\R2010a
) - 将这个目录(
$MATLABHOME\gnumex
)添加到Matlabpath(File->Set Path
在Matlab中File->Set Path
)。
注意:以pipe理员权限运行Matlab。 -
在Matlab中,在提示符下键入
gnumex
。 填写适当的path,如;MinGW_Root = C:\ MinGW32,Cygwin_Root = C:\ cygwin
-
做'
File->Save Config
',然后点击'Make Options file
'。 从gnumexconfiguration窗口退出。
testing:
将mexopts.bat ( %AppData%\MathWorks\MATLAB\R2010a\mexopts.bat
)复制到此 %AppData%\MathWorks\MATLAB\R2010a\mexopts.bat
的工作目录( %UserProfile%\Documents\MATLAB
)。
-
在matlab中,在提示符下执行以下命令:
mex -f mexopts.bat“C:\ Program Files \ MATLAB \ R2010a \ extern \ examples \ mex \ yprime.c”
-
你input时会得到(
%UserProfile%\Documents\MATLAB\yprime.mexw32
);哪个yprime
-
在Matlab提示符处input
>> yprime(1,1:4)
运行它,看看你是否得到2.0000 8.9685 4.0000 -1.0947
。 - 现在只需将mexopts.bat复制到
$MATLABHOME\bin
,它就可以在任何地方工作。
在Linux平台上的Matlab:
-
在Linux提示符处,安装以下内容;
sudo apt-get install gcc g ++ gfortran
-
在Matlab中,在提示符下执行以下命令;
mex -setup
-
可用于mex的选项文件为:
**1**: /usr/local/MATLAB/R2012b/bin/mexopts.sh
:select选项1 。 要testing工作,请在Matlab提示符处执行以下操作;mex“/usr/local/MATLAB/R2012b/extern/examples/mex/yprime.c”
yprime(1,1:4)
如果你得到警告,
Warning: You are using gcc version "4.6.3-1ubuntu5)". The version currently supported with MEX is "4.4.6". For a list of currently supported compilers see: http://www.mathworks.com/support/compilers/current_release/
在Linux提示符下:
-
sudo apt-get install gcc-4.4 g++-4.4 gfortran-4.4
-
sudo gedit /usr/local/MATLAB/R2012b/bin/mexopts.sh
- 在
CC = 'gcc'
,CXX = 'g++'
和FC = 'gfortran'
所有实例中,将CC = 'gcc'
改为'g++-4.4'
,FC = 'gfortran'
。 - 保存该文件并退出。
为什么这么多步骤? 如果你有Matlab 2016或更高版本 ,只需要:
- 下载mingw并安装到一个没有空格的文件夹(也就是不进入“Program Files”)
- 添加指向安装文件夹的
MW_MINGW64_LOC
环境variables(与input到安装程序中完全相同的东西) - 重新启动您的电脑
- 打开MATLAB并在控制台中input
mex -setup
。 应该说“configuration使用MinGW” - 运行/编译你的MATLAB程序
我已经在新的Windows 10个人电脑上testing过了,它可以正常工作!
这个在Windows 8下的Matlab 2012b上工作:
https://github.com/DynareTeam/dynare/blob/master/windows/mexopts-win64.bat
修改cgwin目录或使用mingw目录replace它。 如果您切换到64位版本,也可以更换编译器-exe。
在Windows的64位与R2011a它与http://tdm-gcc.tdragon.net/和http://gnumex.sourceforge.net/,但我必须更改;maxopt.bat
行条目GM_ADD_LIBS
如下:
rem Add path to where dlls are: set DLL_PATH="C:\Program Files\MATLAB\R2011a\bin\win64" rem Add every dll needed: set GM_ADD_LIBS=%DLL_PATH%\libmx.dll %DLL_PATH%\libmex.dll %DLL_PATH%\libmat.dll
我花了很长时间才得到这一点,祝你好运。
我原本以为这听起来像是一种折磨,但是根据@ user10171136的上述回答,我发现从Fedora Linux的Windows mex交叉编译实际上很简单。 Fedora有mingw和mingw64包,所以:
-
sudo yum install mingw64-gcc mingw64-gcc-c++
- 从Windows Matlab复制安装
extern/include
和bin/win64
目录(实际上,您可能只需要一部分头文件和dll的一小部分;libmat.dll libmex.dll libmx.dll
可能是所有你需要的。我把这两个目录放到我现有的Linux MATLAB目录下的一个新的R2010a-w64
目录下;更改下面的命令适合你在哪里隐藏Windows头文件和libs文件。 - 我遇到了一个问题,那就是在
matrix.h
中需要char16_t
,而且没有定义。 我想matrix.h
忘了包含uchar.h
? 我使用了一个-include
指令。 见下文。 -
x86_64-w64-mingw32-gcc -m64 -shared -include uchar.h -I/opt/MATLAB/R2010a-w64/extern/include -DMATLAB_MEX_FILE -L/opt/MATLAB/R2010a-w64/bin/win64 -o bla.mexw64 bla.c -lmx -lmex
- (您可能需要额外的链接库,例如-lmat -leng -lm等)
- 这成功地生成一个mex文件,可以在Windows下执行我的设置。 到目前为止,我只用非常简单的C程序来testing它。
有兴趣听听这听起来是否合理; 我没有太多的交叉编译经验。
这是对这个答案的详细描述。 因此,所有的信贷都应该去那个答案 。
1安装MinGW-w64:
1.1下载这个MinGW64-w64构build及其更新:
1.2安装(解压缩)下载的档案:
1.2.1解压生成文件并将生成的mingw64\
文件夹移到c:\
1.2.2解压并复制(覆盖) c:\mingw64
上的更新文件
1.3将C:\mingw64\bin
添加到Pathvariables中:
set PATH=C:\mingw64\bin;%PATH%
2在命令行上(Matlab环境之外),编译* .c文件:例如, CCODEFILE.c
(假设Matlab 2012b安装在C:\Program Files\MATLAB\R2012b\
文件夹中):
"c:\mingw64\bin\x86_64-w64-mingw32-g++.exe" -m64 -shared -I"C:/Program Files/MATLAB/R2012b/extern/include" -DMATLAB_MEX_FILE -o CCODEFILE.mexw64 -Wl,--export-all-symbols CCODEFILE.c -L"C:/Program Files/MATLAB/R2012b/bin/win64" -lmex -lmx -leng -lmat
3然后,任何Matlab代码在调用CCODEFILE
函数时都应该正常工作。
如果在Windows上使用Matlab2016b的附件工具栏无法安装Mingw-w64 ,则可以使用此解决方法。 请记住,您需要根据安装path更改path。
- Mingw-w64官方网站将您redirect到Win-builds项目,该项目是一组开源工具的包pipe理器。 所以,首先你需要安装Win-build。
- 安装Win-builds时,确保你input的path不包含任何空格,例如
C:\Win-builds
。 - 安装Win-build之后,点击
Process
button来安装Mingw-w64所在的所有软件包。 - 现在你已经安装了Mingw-w64,你需要定义
MW_MINGW64_LOC
环境variables, Matlab使用它来检测Mingw-w64 。 - 要定义环境variables,请执行以下步骤:
$ YOUR_USER_NAME \ New的控制面板\系统\高级系统设置\高级\环境variables\用户variables
- 把
Variable name = MW_MINGW64_LOC
和Variable value = C:\Win-builds
。 注意,Win-builds将所有的可执行文件放在C:\Win-builds\bin
,通过定义这个variables,Matlab将自动扫描寻找gcc.exe
path的bin
文件夹。 - 现在,您已经安装了Mingw-w64并定义了
MW_MINGW64_LOC
环境variables,现在是构build和testingyprime示例的时候了 。 所以启动Matlab并input以下命令(不要忘记修改相应的path):
mex -v'C:\ Program Files \ MATLAB \ R2016b \ extern \ examples \ mex \ yprime.c'
- 成功的安装将显示以下消息:
墨西哥成功完成。
- 最后,你可以通过input
yprime(1,1:4)
来testing你的安装。 答案是:
ans = 2.0000 8.9685 4.0000 -1.0947
在linux上,如果你inputmex -setup
,你可以select编译器。
在Windows上,您应该尝试安装lcc,例如可以通过安装免费的Microsoft Visual Studio Express来实现。