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

Men*_*nyh 20 matlab mingw mex

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

不知道如何设置它?

小智 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*
Run Code Online (Sandbox Code Playgroud)

将此makefile放在源代码目录中make.无需转换DLL文件.


Bog*_*dan 13

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

以下文件适用于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%"
Run Code Online (Sandbox Code Playgroud)

然后你可以尝试在Matlab中这样做:

mex -v p:\matlab\R2012a\extern\examples\mex\yprime.c
which yprime
Run Code Online (Sandbox Code Playgroud)

应该屈服b:\code\m\yprime.mexw64(或当前文件夹是什么).如果你这样做:

yprime(1,1:4)
Run Code Online (Sandbox Code Playgroud)

你应该看到:

ans =
    2.0000    8.9685    4.0000   -1.0947
Run Code Online (Sandbox Code Playgroud)

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

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


cha*_*pjc 8

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

它现在位于支持的编译器列表的顶部.

有关下载MinGW 的官方说明,请参阅此处(他们推荐使用TDB-GCC).

列出了一些限制和警告(如不与其他编译器编译库链接,你必须抓住MEX文件中的例外,等等).

下面是我制作XML文件以执行相同操作的旧方法.


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

保持不变的是你只需要下载并提取MinGW发行版并将MATLAB指向它.目前没有必要MSYS,Cygwin的或gnumex.唯一棘手的部分是将MATLAB指向它,但这是一个解决方案.

精简版

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

长版

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

  1. 从Sourceforge获取w64最新版本(或使用安装程序选择所需的工具链,根据需要选择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和legacy mingw_mexopts.bat.从它作为模板开始,并(可选)使用您下载和提取的MinGW发行版的描述性名称和版本编辑XML文件.
  4. 设置(或创建)MINGWROOT环境变量.这是允许mex命令定位编译器的原因.你可以在MATLAB做到这一点(和每次 MATLAB与启动startup.m脚本userpath)用setenv,或者只是用一次的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++
    
    Run Code Online (Sandbox Code Playgroud)

    输出应如下所示:

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

如果需要,以类似的方式设置C编译器,使用新的XML配置文件,指定C语言,C编译器前端(例如"x86_64-w64-mingw32-gcc.exe",它不会自动链接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++
Run Code Online (Sandbox Code Playgroud)

XML模板中有关于此的注释.有关libpthread-1.dll的信息,请参见此处.

对于TDM-GCC,情况恰恰相反:运行时(包括pthread)自动静态链接.要动态链接,这需要DLL但减少MEX文件大小,您需要:

-shared-libgcc -shared-libstdc++
Run Code Online (Sandbox Code Playgroud)


use*_*136 6

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

如果已安装,则可以从命令行编译.mex文件.有些人可能会说这是第一次有点单调乏味.gccMatlab

首先要做的事 - 你用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
    
    Run Code Online (Sandbox Code Playgroud)
  3. 这将导致一堆链接器错误,例如

    undefined reference to `mexErrMsgTxt'
    
    Run Code Online (Sandbox Code Playgroud)

    为了解决这个问题,就必须建立与连接导入库libmex.dll,libmx.dll,libmat.dlllibeng.dll(你可能有其他人,但这些是主要的)

  4. 列出你缺少的功能,并猜出dll它们来自何处.提示:mexErrMsgTxt来自libmex.dll,因为它以"mex"开头......

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

    EXPORTS
    ... relevant function names go here, such as mexErrMsgTxt, matOpen, etc.
    
    Run Code Online (Sandbox Code Playgroud)
  6. 执行以下命令,以创建导入库:

    x86_64-w64-mingw32-dlltool -d libmx.def --dllname libmx.dll -l libmx.a
    
    Run Code Online (Sandbox Code Playgroud)

    (与其余.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
    
    Run Code Online (Sandbox Code Playgroud)

可以做得更好的事情 - 而不是--export-all-symbol只导出mexFunction(需要创建另一个.def文件,或者__declspec(dllexport)之前添加" " void mexFunction(...)).