使用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,我做了以下设置:

  1. 从Sourceforge获取w64的最新版本 (或使用安装程序select所需的工具链,根据需要selectpthread或Win32线程版本)。
  2. 解压缩它,以便获得编译器的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。
  3. 使用自定义的XMLconfiguration文件进行设置。 在我的GitHub仓库中,我发布了两种文件types的MinGW-w64的C ++configuration: mex_C ++ _ mingw-w64.xml和mingw_mexopts.bat 。 从那开始作为一个模板,并且(可选地)用描述性的名字和你下载并提取的MinGW发布版本来编辑XML文件
  4. 设置(或创build) MINGWROOT环境variables。 这就是允许mex命令find编译器的原因。 你可以在MATLAB中使用setenv来完成这个任务( 每次 MATLAB在userpathstartup.m脚本开始),或者使用Windows属性对话框或本机Windows 7的setx.exe命令执行一次 。
  5. 运行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做到这一点应该很简单。

  1. C:\MinGW-64\bin\到您的path。 你不会后悔的:)
  2. 使用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 
  3. 这将导致一堆链接器错误,如

     undefined reference to `mexErrMsgTxt' 

    为了解决这个问题,你必须创build一个连接libmex.dlllibmx.dlllibmat.dlllibeng.dll的导入库(你可能有其他的,但是这些是主要的)

  4. 列出你错过的function,好吧,猜猜他们是从哪里来的。 提示: mexErrMsgTxt来自libmex.dll ,因为它以“mex”开头。

  5. 对于每个你需要导出的dll ,创build一个.def文件包含

     EXPORTS ... relevant function names go here, such as mexErrMsgTxt, matOpen, etc. 
  6. 执行以下命令来创build导入库:

     x86_64-w64-mingw32-dlltool -d libmx.def --dllname libmx.dll -l libmx.a 

    (与.def文件的其余部分相同)

  7. 现在你很好走!

     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/

设置编译器:

  1. http://tdm-gcc.tdragon.net/download安装;TDM-GCC (C ++编译器"C:\MinGW32\bin;"
  2. 从( http://ptolemy.eecs.berkeley.edu/ptolemyII/ptII4.0/cygwin.htm )安装Cygwin (工具包在Windows平台上提供Unix工具)。
    下载并安装cygwingDevel.exe
  3. 通过( https://sourceforge.net/projects/gnumex )获取gnumex存档并将gnumex提取到( $MATLABHOME\gnumex )。
    例如$MATLABHOMEC:\Program Files\MATLAB\R2010a
  4. 将这个目录( $MATLABHOME\gnumex )添加到Matlabpath( File->Set Path在Matlab中File->Set Path )。
    注意:以pipe理员权限运行Matlab。
  5. 在Matlab中,在提示符下键入gnumex 。 填写适当的path,如;

    MinGW_Root = C:\ MinGW32,Cygwin_Root = C:\ cygwin

  6. 做' 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 )。

  1. 在matlab中,在提示符下执行以下命令:

    mex -f mexopts.bat“C:\ Program Files \ MATLAB \ R2010a \ extern \ examples \ mex \ yprime.c”

  2. 你input时会得到( %UserProfile%\Documents\MATLAB\yprime.mexw32 );

    哪个yprime

  3. 在Matlab提示符处input>> yprime(1,1:4)运行它,看看你是否得到2.0000 8.9685 4.0000 -1.0947

  4. 现在只需将mexopts.bat复制到$MATLABHOME\bin ,它就可以在任何地方工作。

在Linux平台上的Matlab:

  1. 在Linux提示符处,安装以下内容;

    sudo apt-get install gcc g ++ gfortran

  2. 在Matlab中,在提示符下执行以下命令;

    mex -setup

  3. 可用于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提示符下:

  1. sudo apt-get install gcc-4.4 g++-4.4 gfortran-4.4
  2. sudo gedit /usr/local/MATLAB/R2012b/bin/mexopts.sh
  3. CC = 'gcc'CXX = 'g++'FC = 'gfortran'所有实例中,将CC = 'gcc'改为'g++-4.4'FC = 'gfortran'
  4. 保存该文件并退出。

为什么这么多步骤? 如果你有Matlab 2016或更高版本 ,只需要:

  1. 下载mingw并安装到一个没有空格的文件夹(也就是不进入“Program Files”)
  2. 添加指向安装文件夹的MW_MINGW64_LOC环境variables(与input到安装程序中完全相同的东西)
  3. 重新启动您的电脑
  4. 打开MATLAB并在控制台中inputmex -setup 。 应该说“configuration使用MinGW”
  5. 运行/编译你的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包,所以:

  1. sudo yum install mingw64-gcc mingw64-gcc-c++
  2. 从Windows Matlab复制安装extern/includebin/win64目录(实际上,您可能只需要一部分头文件和dll的一小部分; libmat.dll libmex.dll libmx.dll可能是所有你需要的。我把这两个目录放到我现有的Linux MATLAB目录下的一个新的R2010a-w64目录下;更改下面的命令适合你在哪里隐藏Windows头文件和libs文件。
  3. 我遇到了一个问题,那就是在matrix.h中需要char16_t ,而且没有定义。 我想matrix.h忘了包含uchar.h ? 我使用了一个-include指令。 见下文。
  4. 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
  5. (您可能需要额外的链接库,例如-lmat -leng -lm等)
  6. 这成功地生成一个mex文件,可以在Windows下执行我的设置。 到目前为止,我只用非常简单的C程序来testing它。

有兴趣听听这听起来是否合理; 我没有太多的交叉编译经验。

这是对这个答案的详细描述。 因此,所有的信贷都应该去那个答案 。

1安装MinGW-w64:

1.1下载这个MinGW64-w64构build及其更新:

http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/sezero_4.5_20111101/mingw-w64-bin_x86_64-mingw_20111101_sezero.zip/download

http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/sezero_4.5_20111101/sezero_20111101-w64-update-rev.5747.zip/download

http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/sezero_4.5_20111101/README-mingw-w64-20111101_sezero.txt/download

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。

  1. Mingw-w64官方网站将您redirect到Win-builds项目,该项目是一组开源工具的包pipe理器。 所以,首先你需要安装Win-build。
  2. 安装Win-builds时,确保你input的path不包含任何空格,例如C:\Win-builds
  3. 安装Win-build之后,点击Processbutton来安装Mingw-w64所在的所有软件包。
  4. 现在你已经安装了Mingw-w64,你需要定义MW_MINGW64_LOC环境variables, Matlab使用它来检测Mingw-w64 。
  5. 要定义环境variables,请执行以下步骤:

    $ YOUR_USER_NAME \ New的控制面板\系统\高级系统设置\高级\环境variables\用户variables

  6. Variable name = MW_MINGW64_LOCVariable value = C:\Win-builds 。 注意,Win-builds将所有的可执行文件放在C:\Win-builds\bin ,通过定义这个variables,Matlab将自动扫描寻找gcc.exepath的bin文件夹。
  7. 现在,您已经安装了Mingw-w64并定义了MW_MINGW64_LOC环境variables,现在是构build和testingyprime示例的时候了 。 所以启动Matlab并input以下命令(不要忘记修改相应的path):

    mex -v'C:\ Program Files \ MATLAB \ R2016b \ extern \ examples \ mex \ yprime.c'

  8. 成功的安装将显示以下消息:

    墨西哥成功完成。

  9. 最后,你可以通过inputyprime(1,1:4)来testing你的安装。 答案是:

    ans = 2.0000 8.9685 4.0000 -1.0947

在linux上,如果你inputmex -setup ,你可以select编译器。

在Windows上,您应该尝试安装lcc,例如可以通过安装免费的Microsoft Visual Studio Express来实现。