Reputation: 715
I've been given a project to run on MATLAB R2011a. As there are several .c files in there - I need to set up GCC as the MEX compiler for that project. However, I cannot seem to find any explanation as to how to set it up. I've tried a script program called gnumex - but it failed (probably set up for an older version of MATLAB).
Any idea how to set it up?
Upvotes: 22
Views: 62694
Reputation: 114126
Why so many steps? If you have Matlab 2016 or higher, just do:
MW_MINGW64_LOC
environment variable pointing to the install folder (the exact same thing you typed into the installer)mex -setup
into the console. It should say "configured to use MinGW"I've tested these on a new Windows 10 PC and it works!
Upvotes: 1
Reputation: 1912
If you couldn't install Mingw-w64 using the Add-Ons toolbar of Matlab2016b on Windows, you can use this workaround. Keep this in mind that you need to change the paths according to your installation paths.
C:\Win-builds
. Process
button to install all packages where Mingw-w64 is among them.MW_MINGW64_LOC
environment variable which Matlab uses it to detect Mingw-w64. Control panel\ System\ Advanced system settings\ Advanced\ Environment Variable\ User variables for $YOUR_USER_NAME\ New
Variable name = MW_MINGW64_LOC
and Variable value = C:\Win-builds
. Notice that the Win-builds puts all executables in C:\Win-builds\bin
and by defining this variable, Matlab will automatically scans the bin
folder of the path looking for gcc.exe
.MW_MINGW64_LOC
environment variable, it is time to build and test the yprime example. So Launch Matlab and type the following command (Do not forget to modify the path accordingly):
mex -v 'C:\Program Files\MATLAB\R2016b\extern\examples\mex\yprime.c'
MEX completed successfully.
yprime(1,1:4)
. The answer would be:
ans = 2.0000 8.9685 4.0000 -1.0947
Upvotes: 1
Reputation: 30589
It's now at the top of the list of supported compilers.
See here for the official instructions for downloading MinGW (they recommend TDB-GCC).
There are several limitations and caveats listed (e.g. don't link with libraries compiled with other compilers, you have to catch your exceptions inside the MEX file, etc.).
Below is my old way of making an XML file to do the same thing.
The years have gone by and MATLAB (as of R2014a) has moved to a new XML-based system for configuring MEX files. MATLAB still temporariily supports legacy .bat files, for now, but it will bother you about it. Another change is that are distinct C and C++ configurations (more later).
What has stayed the same is that you just need to download and extract a MinGW distribution and point MATLAB to it. There is still no need for MSYS, cygwin or gnumex. The only tricky part is pointing MATLAB to it, but here is a solution.
Short Version
MINGWROOT
environment variable.mex -setup:[xmlfile] [C|C++]
.Long Version
For MinGW-w64, I do the following to set it up:
C:\mingw-w64\x86_64-4.9.2-release-posix-seh-rt_v3-rev1\bin\x86_64-w64-mingw32-g++.exe
. There is no need for MSYS, cygwin, or any other environment if you plan on compiling in MATLAB with the mex
command. Check your PATH
environment variable to make sure you don't have multiple compilers (g++
) on your path, preferably none. Verify with a fresh command prompt.MINGWROOT
environment variable. This is what allows the mex
command to locate the compiler. You can do this in MATLAB (and every time MATLAB starts with a startup.m
script in userpath
) with setenv
, or just once with the Windows properties dialog or the native Windows 7 setx.exe command.Run mex -setup:C:\actual\configFilePath.xml C++
. For example, using the .xml file to set up C++ MEX file compilation:
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++
The output should look like this:
MEX configured to use 'MinGW-w64 GCC 4.9.2 posixthreads seh' for C++ language compilation.
If needed, set up the C compiler in a similar manner with a new XML config file specifying the C language, the C compiler frontend (e.g. "x86_64-w64-mingw32-gcc.exe" which won't automatically link the C++ standard library), adjust the link libraries as needed, compiler flags (e.g. change -std=c++11
to -std=c99
), etc.
Note about static vs. dynamic linking of runtime libraries
Libraries such as a MEX file created with MinGW-w64 as above may depend on a few DLLs (at runtime): LIBGCC_S_SEH-1.DLL (for the seh exception distributions) and LIBSTDC++-6.DLL, and possibly libwinpthread-1.dll if you chose a pthreads distribution instead of Win32 threads. If you don't want to copy these files around, you can statically link the runtime libraries into your MEX file by adding the following switches:
-static-libgcc -static-libstdc++
There's a comment in the XML template about this. See here for info about libpthread-1.dll.
With TDM-GCC, the opposite is true: the runtimes (including pthread) are statically linked automatically. To link dynamically, which will require the DLLs but reduce your MEX file size, you need:
-shared-libgcc -shared-libstdc++
Upvotes: 9
Reputation: 151
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!
EDIT Oct 2014: I now use an improved mexopts.bat file than the above with a different MinGW64 (yields slightly faster binary code than TDM's). See my homepage for details and downloads.
Upvotes: 15
Reputation: 1981
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:
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.
Upvotes: 1
Reputation: 170
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.
Upvotes: 15
Reputation: 2138
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++
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.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
Interested to hear if this sounds reasonable; I don't have much experience with cross-compiling.
Upvotes: 0
Reputation: 15725
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.
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(...)
).
Upvotes: 6
Reputation: 173
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.
Upvotes: 0
Reputation: 9
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.
Upvotes: 0
Reputation: 277
Matlab links to external code (C++, Fortran, Java etc) using MEX files. (http://gnumex.sourceforge.net/)
"C:\MinGW32\bin;"
) from http://tdm-gcc.tdragon.net/downloadcygwingDevel.exe
$MATLABHOME\gnumex
). $MATLABHOME
would be for example (C:\Program Files\MATLAB\R2010a
)$MATLABHOME\gnumex
) to the Matlab path (File->Set Path
in Matlab). 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.
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
.
$MATLABHOME\bin
and it should work from anywhere.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
'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'
.Upvotes: 1
Reputation: 15725
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
Upvotes: 4
Reputation: 16065
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.
Upvotes: -2