Using GCC(minGW) as Matlab's MEX compiler

来源:互联网 发布:java 线程 wait 编辑:程序博客网 时间:2024/05/18 00:48

http://stackoverflow.com/questions/8552580/using-gccmingw-as-matlabs-mex-compiler




13
down vote
favorite
13
I've been given a project to run on matlab 2011a. As there are several .c files in there - i need to set up GCC as the MEX compiler for that project. However, i can not seem to find any explanation as to how to set it up. I've tried a script program called gnumex - but it failed (probebly set up for an older version of matlab).


Any idea how to set it up??


Thanks!


matlab mingw mex
share|improve this question
edited Aug 4 '12 at 14:37


Amro
65k978179
asked Dec 18 '11 at 15:05


Menyh
2991217
add comment
10 Answers
activeoldestvotes
up vote
9
down vote
accepted
In Matlab 2011b, just compile and link directly in mingw64 or cygwin environment.


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*
Put this makefile on the source code directory and make. No dll files conversion needed.


share|improve this answer
edited Dec 9 '13 at 6:29


Shai
20.2k102952
answered Feb 26 '12 at 7:36


Richard Dualmann
10613
add comment


up vote
6
down vote
Why not adjust the mexopts.bat file in your directory? That way you can use the "mex" command transparently to compile anything, as usual in MATLAB, the same as if it was configured by MATLAB using mex -setup. I'm surprised nobody did this before.


The file below is for x64 version of Matlab and Mingw. I'm using the TDM Mingw64 distribution, which I installed in p:\mingw64-tdm. I have Matlab installed in p:\matlab\R2012a -- edit those accordingly.


This is the mexopts.bat file I'm using, copy paste this in %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%"
Then you can just try doing this in Matlab:


mex -v p:\matlab\R2012a\extern\examples\mex\yprime.c
which yprime
Should yield b:\code\m\yprime.mexw64 (or whatever the current folder is). Then if you do:


yprime(1,1:4)
You should see:


ans =
    2.0000    8.9685    4.0000   -1.0947
Which means you're in business. Good luck!


share|improve this answer
edited Sep 17 '12 at 18:25


answered Sep 16 '12 at 21:38


Bogdan
6112
1  
Thanks; very helpful! I ran into two additional issues. First I had one of the Matlab versions where linking erroneously gets a getValidInputLinkLibraries added to the end of the command. You have to fix this by going into Matlab's bin directory and editing mex.pl to change a getValidInputLinkLibraries line to getValidInputLinkLibraries(). Second, I was getting complaint from matrix.h that char16_t was undefined. It appears uchar.h is not included properly. So I added -include uchar.h to the COMPFLAGS and that seemed to fix it. –  Chinasaur Dec 9 '13 at 5:04 
add comment
up vote
4
down vote
EDIT: There seems to be a much better way with MinGW; see my other answer.


You can compile a .mex file using gcc if you have Matlab installed, from the command line. Some might say it's a little tedious the first time.


First things first - what Matlab do you use? if it's 64-bits, MinGW won't help you, because it's 32-bit. I will therefore show how to use MinGW-w64 instead. Understanding how to do this with 32-bit MinGW should be straightforward.


Add C:\MinGW-64\bin\ to your path. You won't regret this :)
Compile your .c files using 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
This will result in a bunch of linker errors, such as


undefined reference to `mexErrMsgTxt'
To solve this problem, you'll have to create an import library which connects with libmex.dll, libmx.dll, libmat.dll and libeng.dll (you might have others, but these are the main ones)


List the functions you're missing, and, well, guess what dll they're coming from. Hint: mexErrMsgTxt is from libmex.dll, because it starts with "mex"...


For every dll you need to export, create a .def file containing


EXPORTS
... relevant function names go here, such as mexErrMsgTxt, matOpen, etc.
Execute the following command, to create import libraries:


x86_64-w64-mingw32-dlltool -d libmx.def --dllname libmx.dll -l libmx.a
(Same for the rest of the .def files)


Now you're good to go!


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
Things which can be done better - instead of --export-all-symbol, only export mexFunction (requires creating another .def file, or adding "__declspec(dllexport)" before void mexFunction(...)).


share|improve this answer
edited Dec 8 '13 at 5:57


answered Dec 18 '11 at 16:44


user1071136
6,08111233
 
Crap, its 64 bit :( –  Menyh Dec 18 '11 at 21:49
 
Ok, I fixed the instructions (there are lots of fixes), and (ahem) actually did the thing and ran the result on Matlab - it seems to work for a simple mex file. It's actually quite exciting! I didn't know it's possible. And I didn't know that MinGW64 exists and works. So thanks. :) –  user1071136 Dec 18 '11 at 22:50 
 
Thanks for your time mate. –  Menyh Dec 19 '11 at 7:00
 
It's not the Windows bitness that matters, but the MATLAB bitness. For example, student editions are 32-bit even on 64-bit versions of Windows. –  Ben Voigt Dec 8 '13 at 1:52
 
Yep, that's correct. Edited. –  user1071136 Dec 8 '13 at 5:56
add comment
up vote
3
down vote
MinGW is capable of direct-linking a DLL; that is, it will create a kind of an import library on the fly when linking.


This means compilation can be performed in one step:


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
share|improve this answer
answered Feb 26 '12 at 12:33


user1071136
6,08111233
 
Thanks; very helpful! FYI, based on issues I had with related methods (see other answers) it seems like some versions of Matlab might also require a -include uchar.h to avoid a complaint from matrix.h about missing char16_t. –  Chinasaur Dec 9 '13 at 5:15 
add comment
up vote
2
down vote
Matlab links to external code (C++, Fortran, Java etc) using MEX files. (http://gnumex.sourceforge.net/)


Setting up Compiler:


Install TDM-GCC (C++ Compiler "C:\MinGW32\bin;") from http://tdm-gcc.tdragon.net/download
Install Cygwin (toolkit provides Unix tools on the Windows platform) from (http://ptolemy.eecs.berkeley.edu/ptolemyII/ptII4.0/cygwin.htm). 
Download and Install cygwingDevel.exe
Obtain the gnumex archive via (https://sourceforge.net/projects/gnumex) and extract the gnumex to ($MATLABHOME\gnumex). 
Where $MATLABHOME would be for example (C:\Program Files\MATLAB\R2010a)
Add this directory ($MATLABHOME\gnumex) to the Matlab path (File->Set Path in Matlab). 
Note: Run Matlab with Administrator priviledges.
In Matlab, type gnumex at the prompt. Fill in appropriate paths like;


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


Do 'File->Save Config', then click 'Make Options file'. Exit from gnumex configure window.


Testing:


Copy mexopts.bat (%AppData%\MathWorks\MATLAB\R2010a\mexopts.bat) to the working directory (%UserProfile%\Documents\MATLAB) for this test.


In matlab, execute the following at prompt;


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


You get (%UserProfile%\Documents\MATLAB\yprime.mexw32) when you type;


which yprime


Run it by typing at Matlab prompt >> yprime(1,1:4) and see if you get 2.0000 8.9685 4.0000 -1.0947.


Now just copy mexopts.bat to $MATLABHOME\bin and it should work from anywhere.
Matlab on Linux Platform:


At Linux prompt, install the following;


sudo apt-get install gcc g++ gfortran


In Matlab, execute the following at prompt;


mex -setup


The options files available for mex are: **1**: /usr/local/MATLAB/R2012b/bin/mexopts.sh : Select option 1. To test the working, execute the following at Matlab prompt;


mex "/usr/local/MATLAB/R2012b/extern/examples/mex/yprime.c"


yprime(1,1:4)


In case you get the warning;


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/
At Linux prompt:


sudo apt-get install gcc-4.4 g++-4.4 gfortran-4.4
sudo gedit /usr/local/MATLAB/R2012b/bin/mexopts.sh
Change 'gcc' to 'gcc-4.4' ,'g++' to 'g++-4.4' , 'gfortran' to 'gfortran-4.4' at all instances of  CC = 'gcc' , CXX = 'g++' and FC = 'gfortran'.
Save the file and exit.
share|improve this answer
edited May 16 '13 at 11:06


answered Jan 9 '13 at 15:20


Faheem
894
add comment
up vote
1
down vote
This one works on Matlab 2012b under Windows 8:


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


Modify cgwin directory or replace it with mingw directory if used. You can also echange the compiler-exe if you switch to a 64 bit version.


share|improve this answer
edited May 16 '13 at 11:14


Shai
20.2k102952
answered Feb 23 '13 at 18:33


pete
111
add comment
up vote
0
down vote
In Windows 64 bit with R2011a it worked with http://tdm-gcc.tdragon.net/ and http://gnumex.sourceforge.net/ but I have to change maxopt.bat line entry GM_ADD_LIBS as follows:


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 
It took me a long time to get to this point, good luck.


share|improve this answer
edited Nov 23 '13 at 15:27


Tomdarkness
1,6871517
answered Nov 23 '13 at 15:03


rarias
1
add comment
up vote
0
down vote
I originally thought this sounded like a form of torture, but based on the above answer by @user10171136 I actually found it pretty straightforward to cross-compile for Windows mex from Fedora Linux. Fedora has mingw and mingw64 packages, so:


sudo yum install mingw64-gcc mingw64-gcc-c++
Copy over from a Windows Matlab install both the extern/include and bin/win64 directories (actually you probably only need a subset of the headers and a small subset of the dlls; libmat.dll libmex.dll libmx.dll might be all you need. I put these two directories into a new R2010a-w64 directory under my existing Linux MATLAB directory; change the below commands appropriate for where you stashed the Windows headers and libs.
There was one problem I ran into, which is that char16_t was needed in matrix.h and wasn't defined. I guess matrix.h forgot to include uchar.h? I worked around with an -include directive; see below.
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
(You may need additional libraries for linking, e.g. -lmat -leng -lm, etc.)
This successfully generates a mex file that is executable under Windows Matlab for my setup. So far I've only tested this with pretty simple C programs.
Interested to hear if this sounds reasonable; I don't have much experience with cross-compiling.


share|improve this answer
edited Dec 9 '13 at 5:18


answered Dec 7 '13 at 21:24


Chinasaur
8491813
add comment
up vote
0
down vote
This is a detailed walkthorugh of this answer. Therefore, all the credit should go to that answer.


1 Install MinGW-w64:


1.1 Download this MinGW64-w64 build and its update:


(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 Install (unzip) the downloaded archives:


1.2.1 Unzip the build file and move the resulting mingw64\ folder in c:\


1.2.2 Unzip and copy (overwrite) the update file on c:\mingw64


1.3 Add C:\mingw64\bin to the Path variable:


set PATH=C:\mingw64\bin;%PATH%
2 On a commandline (outside Matlab environment), compile your *.c files: For example, CCODEFILE.c (Assuming Matlab 2012b installed in C:\Program Files\MATLAB\R2012b\ folder):


"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 Then, any Matlab code should work fine when it calls the CCODEFILE function.


share|improve this answer
answered Dec 20 '13 at 19:56


imriss
1209
add comment
up vote
-2
down vote
On linux, if you type mex -setup, you can choose the compiler.


On windows, you should try to install lcc, you can do so for instance by installing Microsoft Visual Studio Express, which is free.


share|improve this answer
edited Dec 18 '11 at 16:23


answered Dec 18 '11 at 15:47


Oli
9,14421133
 
On Windows you can't. –  user1071136 Dec 18 '11 at 15:49
 
ok, I edited, I did not get that he was on windows. But are you sure that mex -setup does not work on windows? I think I already used it. I am too lazy to reboot my laptop on windows to check... –  Oli Dec 18 '11 at 16:01
2  
lcc is not the Microsoft compiler. –  rubenvb Dec 18 '11 at 16:01
1  
lcc comes bundled along the 32 bits version of Matlab for Windows. 64 bits version doesn't come with any bundled compiler. The free Visual Studio Express is also deprecated since 2008 and isn't supported anymore in newest versions of Matlab. –  Soravux Oct 5 '13 at 17:49
 
@Soravux: Visual Studio Express certainly isn't deprecated. Perhaps you meant to speak only about MATLAB support for it? –  Ben Voigt Dec 8 '13 at 1:53

0 0
原创粉丝点击