【问题标题】:Using GCC (MinGW) as MATLAB's MEX compiler使用 GCC (MinGW) 作为 MATLAB 的 MEX 编译器
【发布时间】:2012-01-23 01:36:06
【问题描述】:

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

知道如何设置吗?

【问题讨论】:

  • 从 R2015b 开始,MinGW 现在是受支持的编译器。见below。考虑升级或提供您自己的 XML 配置文件。

标签: matlab mingw mex


【解决方案1】:

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

以下文件适用于 x64 版本的 Matlab 和 Mingw。我正在使用TDM Mingw64 发行版,它安装在p:\mingw64-tdm 中。我在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

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

2014 年 10 月编辑:我现在使用改进的 mexopts.bat 文件,使用不同的 MinGW64(生成的二进制代码比 TDM 稍快)。有关详细信息和下载,请参阅my homepage

【讨论】:

  • 谢谢;非常有帮助!我遇到了另外两个问题。首先,我有一个 Matlab 版本,其中链接错误地将getValidInputLinkLibraries 添加到命令末尾。您必须通过进入 Matlab 的 bin 目录并编辑 mex.pl 以将 getValidInputLinkLibraries 行更改为 getValidInputLinkLibraries() 来解决此问题。其次,我收到了来自matrix.h 的投诉,称char16_t 未定义。似乎没有正确包含uchar.h。所以我在COMPFLAGS 中添加了-include uchar.h,这似乎解决了它。
  • 这对我来说很好,虽然我必须添加引号,因为我的 matlab 文件夹位于 C:\Program Files\...
  • 修复了双引号问题,谢谢(我听说“程序文件”、System32、SysWOW64 命名以及 Comic Sans 字体都是由微软的同一个人发明的。他感动了很多人)。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    从 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 位选项)。
    • 自定义 XML 配置文件,使用 this one 作为模板(详细信息在下面的长版本中)。
    • 设置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如果您打算在 MATLAB 中使用mex 命令进行编译,则不需要 MSYS、cygwin 或任何其他环境。检查您的 PATH 环境变量以确保您的路径上没有多个编译器 (g++),最好没有。使用新的命令提示符进行验证。
    3. 使用自定义 XML 配置文件进行设置。在我的 GitHub 存储库中,我以两种文件类型发布了 MinGW-w64 的 C++ 配置:mex_C++_mingw-w64.xml 和旧版mingw_mexopts.bat。从它作为模板开始,(可选)使用您下载和提取的 MinGW 发行版的描述性名称和版本编辑 XML 文件
    4. 设置(或创建)MINGWROOT 环境变量。这就是允许mex 命令定位编译器的原因。您可以在 MATLAB 中使用setenv 执行此操作(并且每次MATLAB 都以userpath 中的startup.m 脚本开始),或者仅使用Windows properties dialog 或本机Windows 7 @987654334 执行一次@。
    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++ 语言编译。

    如果需要,以类似的方式设置 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++
    

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

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

    -shared-libgcc -shared-libstdc++
    

    【讨论】:

      【解决方案4】:

      编辑:MinGW 似乎有更好的方法;查看我的其他答案。

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

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

      1. C:\MinGW-64\bin\ 添加到您的路径中。你不会后悔的:)
      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'
        

        要解决这个问题,您必须创建一个与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
        

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

      【讨论】:

      • 好的,我修复了说明(有很多修复),并且(嗯)实际上做了这件事并在 Matlab 上运行了结果——它似乎适用于一个简单的mex 文件。这实际上非常令人兴奋!我不知道这是可能的。而且我不知道MinGW64 存在并且有效。那谢谢啦。 :)
      • 重要的不是 Windows 位数,而是 MATLAB 位数。例如,即使在 64 位版本的 Windows 上,学生版也是 32 位的。
      【解决方案5】:

      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
      

      【讨论】:

      • 谢谢;非常有帮助!仅供参考,根据我在相关方法中遇到的问题(请参阅其他答案),似乎某些版本的 Matlab 可能还需要-include uchar.h 以避免来自matrix.h 的关于缺少char16_t 的投诉。
      【解决方案6】:

      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)。
        例如,$MATLABHOME 在哪里 (C:\Program Files\MATLAB\R2010a)
      4. 将此目录($MATLABHOME\gnumex)添加到 Matlab 路径(File->Set Path 在 Matlab 中)。
        注意:以管理员权限运行 Matlab。
      5. 在 Matlab 中,在提示符处键入 gnumex。填写适当的路径,例如;

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

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

      测试:

      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,它应该可以在任何地方工作。

      Linux 平台上的 Matlab:

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

        sudo apt-get install gcc g++ gfortran

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

        mex 设置

      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)

      如果您收到警告;

      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' 的所有实例中将'gcc' 更改为'gcc-4.4''g++''g++-4.4''gfortran''gfortran-4.4'
      4. 保存文件并退出。

      【讨论】:

        【解决方案7】:

        这是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 函数时都应该可以正常工作。

        【讨论】:

        • @mlnthr 指出第二个 sourceforge 链接已损坏。
        【解决方案8】:

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

        1. Mingw-w64 官方网站将您重定向到Win-builds 项目,该项目是一组开源开发工具的包管理器。所以,首先你需要安装 Win-builds。
        2. 在安装 Win-build 时,请确保您输入的是 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

        【讨论】:

          【解决方案9】:

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

          1. 下载mingw 并安装到没有空格的文件夹中(即不要安装到“程序文件”中)
          2. 添加指向安装文件夹的MW_MINGW64_LOC 环境变量(与您在安装程序中键入的内容完全相同)
          3. 重启电脑
          4. 打开 MATLAB 并在控制台中输入 mex -setup。它应该说“配置为使用 MinGW”
          5. 运行/编译您的 MATLAB 程序

          我已经在一台新的 Windows 10 PC 上测试了这些,并且可以正常工作!

          【讨论】:

          • 最简单的答案!工作完美。谢谢!
          • 试过了,但没用。在 Win10 64 位上的 Matlab R2019b。即使system('gcc --version') 给出了预期的输出......
          【解决方案10】:

          这个在 Windows 8 下的 Matlab 2012b 上工作:

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

          修改 cgwin 目录或使用 mingw 目录替换它。如果您切换到 64 位版本,您还可以更改编译器-exe。

          【讨论】:

            【解决方案11】:

            在带有 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 
            

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

            【讨论】:

              【解决方案12】:

              我最初认为这听起来像是一种折磨,但根据@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. 我遇到了一个问题,即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 Matlab 下为我的设置执行。到目前为止,我只使用非常简单的 C 程序对此进行了测试。

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

              【讨论】:

                【解决方案13】:

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

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

                【讨论】:

                • 好的,我编辑了,我没有得到他在 Windows 上。但是您确定mex -setup 在Windows 上不起作用吗?我想我已经用过了。我懒得在 Windows 上重新启动我的笔记本电脑来检查...
                • lcc 不是 Microsoft 编译器。
                • lcc 捆绑在 32 位版本的 Matlab for Windows 中。 64 位版本不附带任何捆绑的编译器。免费的 Visual Studio Express 自 2008 年以来也已弃用,并且在最新版本的 Matlab 中不再支持。
                • @Soravux:Visual Studio Express 肯定不会被弃用。也许您只想谈论 MATLAB 对它的支持?
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2022-01-11
                • 2015-02-13
                • 2014-05-29
                • 2015-01-10
                • 1970-01-01
                相关资源
                最近更新 更多