使用GCC(MinGW)作为MATLAB的MEX编译器

时间:2011-12-18 15:05:04

标签: matlab mingw mex

我已经获得了一个在MATLAB R2011a上运行的项目。因为那里有几个.c文件 - 我需要将GCC设置为该项目的MEX编译器。但是,我似乎无法找到有关如何设置它的任何解释。我已经尝试过一个名为gnumex的脚本程序 - 但它失败了(可能是为旧版本的MATLAB设置的)。

知道如何设置吗?

13 个答案:

答案 0 :(得分:14)

在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文件。

答案 1 :(得分:13)

为什么不调整目录中的mexopts.bat文件?这样你可以透明地使用“mex”命令来编译任何东西,就像在MATLAB中一样,就像它是由MATLAB使用mex -setup配置的一样。我很惊讶没有人这样做过。

以下文件适用于Matlab和Mingw的x64版本。我正在使用我在p:\mingw64-tdm中安装的TDM Mingw64发行版。我在p:\matlab\R2012a安装了Matlab - 相应地编辑它们。

这是我正在使用的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 -v p:\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

这意味着你在做生意。祝你好运!

EDIT 2014年10月:我现在使用改进的mexopts.bat文件而不是上面的MinGW64(产生比TDM快一点的二进制代码)。有关详细信息和下载,请参阅my homepage

答案 2 :(得分:8)

从MATLAB R2015b开始,MinGW正式受到支持!

它现在位于list of supported compilers的顶部。

请参阅here for the official instructions下载MinGW(他们推荐使用TDB-GCC)。

several limitations and caveats listed(例如,不与使用其他编译器编译的库链接,您必须在MEX文件中捕获异常等)。

下面是我制作XML文件的旧方法。


多年过去了, MATLAB(从R2014a开始)已经转移到一个新的基于XML的系统来配置MEX文件。到目前为止,MATLAB仍然暂时支持传统的.bat文件,但它将bother you about it。另一个变化是不同的C和C ++配置(稍后)。

保持不变的是您只需要下载并提取MinGW发行版并将MATLAB指向它。 仍然不需要MSYS,cygwin或gnumex。唯一棘手的部分是将MATLAB指向它,但这是一个解决方案。

短版

  • 下载并解压缩MinGW发行版。选择一个,例如MinGW-w64(64位)或TDM-GCC(32位和64位选项)。
  • 使用this one作为模板自定义XML配置文件(详见下面的长版)。
  • 设置MINGWROOT环境变量。
  • 运行mex -setup:[xmlfile] [C|C++]

长版

对于MinGW-w64,我执行以下操作进行设置:

  1. 抓住latest revision for w64 from Sourceforge(或使用the installer选择所需的工具链,根据需要选择pthread或Win32线程版本。
  2. 将其解压缩,以便您拥有编译器的路径,如C:\mingw-w64\x86_64-4.9.2-release-posix-seh-rt_v3-rev1\bin\x86_64-w64-mingw32-g++.exe如果您打算使用mex命令在MATLAB中进行编译,则不需要MSYS,cygwin或任何其他环境。检查您的PATH环境变量,确保您的路径中没有多个编译器(g++),最好是没有。使用全新的命令提示符进行验证。
  3. 使用自定义XML配置文件进行设置。在我的GitHub回购中,我已经在两种文件类型中发布了MinGW-w64的C ++配置:mex_C++_mingw-w64.xml和遗留mingw_mexopts.bat。从该模板开始,(可选)使用您下载和解压缩的MinGW发行版的描述性名称和版本编辑XML文件
  4. 设置(或创建)MINGWROOT环境变量。这是允许mex命令定位编译器的原因。您可以在MATLAB中执行此操作(每次 MATLAB以startup.m中的userpath脚本开头)setenv,或只使用Windows properties dialog一次或本机Windows 7 setx.exe command
  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++
    

    输出应如下所示:

      

    MEX配置为使用' MinGW-w64 GCC 4.9.2 posixthreads seh' 进行C ++语言编译。

  6. 如果需要,以类似的方式设置C编译器,使用新的XML配置文件指定C语言,C编译器前端(例如" x86_64-w64-mingw32-gcc.exe"赢得& #39; t自动链接C ++标准库),根据需要调整链接库,编译标记(例如将-std=c++11更改为-std=c99)等。


    关于运行时库的静态与动态链接的注意事项

    如上所述使用MinGW-w64创建的MEX文件库可能依赖于一些DLL(在运行时):LIBGCC_S_SEH-1.DLL(用于seh异常分发)和LIBSTDC ++ - 6.DLL,以及可能的libwinpthread- 1.dll如果您选择了pthreads分发而不是Win32线程。如果您不想复制这些文件,可以通过添加以下开关将运行时库静态链接到MEX文件中:

    -static-libgcc -static-libstdc++
    

    XML模板中有关于此的评论。有关libpthread-1.dll的信息,请参阅here

    使用TDM-GCC,the opposite is true:运行时(包括pthread)自动静态链接。要动态链接,这需要DLL但减少MEX文件大小,您需要:

    -shared-libgcc -shared-libstdc++
    

答案 3 :(得分:6)

编辑:MinGW似乎有更好的方法;看到我的另一个答案。

如果您已从命令行安装.mex,则可以使用gcc编译Matlab文件。有些人可能会说这是第一次有点乏味。

首先要做的事 - 你用Matlab做什么?如果它是64位,MinGW将无法帮助你,因为它是32位。因此,我将展示如何使用MinGW-w64。了解如何使用32位MinGW执行此操作应该很简单。

  1. C:\MinGW-64\bin\添加到您的路径中。你不会后悔:)
  2. 使用.c编译gcc个文件:

    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'
    

    要解决此问题,您必须创建一个与libmex.dlllibmx.dlllibmat.dlllibeng.dll相关联的导入库(您可能还有其他人,但是这些是主要的)

  4. 列出您缺少的功能,并且,猜猜它们来自哪个dll。提示:mexErrMsgTxt来自libmex.dll,因为它以“mex”开头......

  5. 对于您需要导出的每个dll,请创建一个包含

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

    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
    
  8. 可以做得更好的事情 - 而不是--export-all-symbol,只导出mexFunction(需要创建另一个.def文件,或在__declspec(dllexport)之前添加“void mexFunction(...)”。

答案 4 :(得分:3)

MinGW能够direct-linking a DLL;也就是说,它会在链接时动态创建一种导入库。

这意味着可以一步完成编译:

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

答案 5 :(得分:1)

Matlab使用MEX文件链接到外部代码(C ++,Fortran,Java等)。 (http://gnumex.sourceforge.net/

设置编译器:

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

      

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

  7. 执行“File->Save Config”,然后点击“Make Options file”。退出gnumex配置窗口。

  8. 测试:

    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. 键入时会得到(%UserProfile%\Documents\MATLAB\yprime.mexw32);

        

      哪个yprime

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

    4. 现在只需将 mexopts.bat 复制到$MATLABHOME\bin,它就可以在任何地方使用。
    5. 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:选择选项 1 。要测试工作,请在Matlab提示符处执行以下命令;

          

        mex“/usr/local/MATLAB/R2012b/extern/examples/mex/yprime.c”

             

        yprime(1,1:4)

      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. 在所有[{1}} 'gcc'的实例中,将'gcc-4.4'更改为'g++',将'g++-4.4'更改为'gfortran',将'gfortran-4.4'更改为CC = 'gcc',{ {1}}和CXX = 'g++'
        4. 保存文件并退出。

答案 6 :(得分:1)

这是this answer的详细步骤。因此,所有信用都应转到that answer

1安装MinGW-w64:

1.1下载此MinGW64-w64版本及其更新:

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添加到Path变量:

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函数时都能正常工作。

答案 7 :(得分:1)

如果您无法使用Windows上 Matlab2016b的附加组件工具栏安装 Mingw-w64 ,则可以使用此解决方法。请记住,您需要根据安装路径更改路径。

  1. Mingw-w64官方网站将您重定向到Win-builds项目,该项目是一组开源开发工具的软件包管理器。所以,首先你需要安装Win-builds。
  2. 安装Win-builds时,请确保输入path that does not contain any spaces,例如C:\Win-builds
  3. 安装Win-builds后,只需点击Process按钮即可安装其中包含Mingw-w64的所有软件包。
  4. 现在您安装了Mingw-w64,您需要定义MW_MINGW64_LOC环境变量Matlab uses it to detect Mingw-w64
  5. 要定义环境变量,请执行以下步骤:
      

    控制面板\系统\高级系统设置\高级\环境变量\ $ YOUR_USER_NAME的用户变量\新

  6. Variable name = MW_MINGW64_LOCVariable value = C:\Win-builds。请注意,Win-builds将所有可执行文件放在C:\Win-builds\bin中,通过定义此变量,Matlab将自动扫描路径的bin文件夹,查找gcc.exe
  7. 现在你已经安装了Mingw-w64并定义了MW_MINGW64_LOC环境变量,现在是构建和测试yprime example的时候了。所以启动Matlab并输入以下命令(不要忘记相应地修改路径):
      

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

  8. 安装成功后会显示以下消息:
      

    MEX成功完成。

  9. 最后,您可以输入yprime(1,1:4)来测试您的安装。答案是:
      

    ans = 2.0000 8.9685 4.0000 -1.0947

答案 8 :(得分:1)

为什么这么多步骤?如果您有 Matlab 2016或更高版本,请执行以下操作:

  1. 下载mingw并安装到没有空格的文件夹(即不要进入“程序文件”)
  2. 添加指向安装文件夹的MW_MINGW64_LOC环境变量(与安装程序中输入的内容完全相同)
  3. 重启电脑
  4. 打开MATLAB并在控制台中输入mex -setup。它应该说“配置为使用MinGW”
  5. 运行/编译您的MATLAB程序
  6. 我已经在新的Windows 10 PC上测试了它们,它可以正常工作!

答案 9 :(得分:0)

这个适用于Windows 8下的Matlab 2012b:

https://github.com/DynareTeam/dynare/blob/master/windows/mexopts-win64.bat

修改cgwin目录或将其替换为mingw目录(如果使用)。如果切换到64位版本,也可以更换compiler-exe。

答案 10 :(得分:0)

在使用R2011a的Windows 64位中,它与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 

我花了很长时间才到达这一点,祝你好运。

答案 11 :(得分:0)

我原本以为这听起来像是一种折磨,但基于@ 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标头和库的位置。
  3. 我遇到了一个问题,即char16_t中需要matrix.h并且未定义。我想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. 这为我的设置成功生成了一个可在Windows Matlab下执行的mex文件。到目前为止,我只用非常简单的C程序对它进行了测试。
  7. 有兴趣听听这听起来是否合理;我对交叉编译没有多少经验。

答案 12 :(得分:-2)

在linux上,如果键入mex -setup,则可以选择编译器。

在Windows上,你应该尝试安装lcc,你可以这样做,例如安装免费的Microsoft Visual Studio Express。