There are two attractions to using gcc for Windows over other compilers. The first is that gcc is free. The second is that gcc, particularly Cygwin gcc (see below), can emulate Unix functionality within Windows, so you may be able to use the same c or c++ mex source files on Unix and Windows. The last is that you may also be able to use gcc to compile Fortran programs.
There are two main options when using gcc with Windows: MINimalist Gcc for Windows (Mingw), and the gcc that comes as part of the Cygwin package. The differences between these two, and some other versions of gcc for Windows, are explained in a page on gcc versions for Windows. In brief, the Mingw approach is to simply link to the Microsoft run-time libararies, which results in fast executables, but a restricted compatibility with gcc for Unix. In contrast, the Cygwin gcc compiles link to a dynamic link library, cygwin1.dll, which provides a Unix style API that allows access to many more Unix routines than are available with the Microsoft libraries. See the Cygwin FAQ for more on the Cygwin API and how the Unix emulation works. Cygwin gcc executables tend to be a little slower, and require that the Cygwin1.dll file be on the Windows PATH. Cygwin comes complete with many useful Unix tools, such as the bash shell, and all the usual Unix utilities.
As an added complication, you can also do Mingw compiles using the Cygwin tools, i.e. use the Cygwin tools to link to the Microsoft libraries. This is achieved by passing a flag to the Cygwin gcc, -mno-cygwin. I refer to this as Cygwin/mingw compiling. There are some problems with this option. Although the gnumex utilities here do support Cygwin-mingw compiles, I would strongly suggest using Mingw instead. There have been rumblings on the Cygwin mailing list about discontinuation for -mno-cygwin support, but it is still being updated.This page introduces an archive of routines that I have packaged, called "gnumex". You can find the latest version via the gnumex project SourceForge page. The routines are released under the GNU general public licence. Gnumex allows you to set up the Windows versions of gcc to compile mex files. In the archive are some perl scripts, a Matlab ui setup routine and a couple of supporting mex file dlls, with source. Original scripts and some working mex option .bat files were written by Ton van Overbeek. Lars Gregerson and Mark Levedahl have offered helpful modifications. Christian Merkwirth helped with getting C++ compiles working. Thanks also to Mumit Khan for helpful discussion on dll issues. The original scripts first appeared on the Cygnus (now Cygwin) mailing list.
This is exceptionally easy; have a look first at the Mingw dowload page. In essence it is more or less as easy as just downloading the Mingw executable MingW installer available via links from the Mingw site, and unpacking into a suitable directory, perhaps 'c:\mingw'. The current version at time of writing is MingW-3.1.0-1.exe.
Also consider putting cygwin1.dll somewhere on your windows path, so your mex files can run outside Matlab sessions started in Cygwin bash. Be careful if you copy the cygwin1.dll to somewhere outside its rightful home in the Cygwin distribution; you will at very least have to be careful to update this version of the cygwin1.dll file each time you update the Cygwin distribution, otherwise you will get odd effects from the clashes of the old dll with the new version.
You should now have a working installation of Cygwin and its very useful version of the Bourne Again Shell, bash.
Obtain the gnumex archive via the gnumex project SourceForge page. Unpack the archive (using tar, winzip, whatever) into a directory of your choice - say c:\gnumex. You now have: a Matlab install routine, gnumex.m; a couple of mex file supporting routines (shortpath.dll, uigetpath.dll); a hacked version of the windows dll utility, dlltool, and some perl scripts. The source for the mex files are in the the src subdirectory. For convenience, you might consider putting the directory containing gnumex.m and the dlls onto your Matlab path.
The hacked version of dlltool is to allow linking of fortran routines to the matlab 5 fortran libraries - see a general description of the problem. The patch applied to create the hacked version of dlltool is also included. The patch is to the binutils 2.11.92 source.
The gnumex script will write a bat file that configures the mex compiling routine to use gcc. When you run mex from Matlab, or from the command line, you run the file mex.bat in the Matlab bin directory. This is a strange combination of bat file and perl script, that reads key variables out of another bat file to get compile and link options. This options bat file is by default called mexopts.bat, and may well reside in your Matlab bin directory. You can tell which options file mex is using by running "mex -v" from the Matlab prompt.
To run the gnumex script, start Matlab, change directory to the gnumex directory you selected earlier (e.g c:\gnumex above). Then type "gnumex" from the Matlab prompt. A Matlab figure window comes up, with a variety of options, which should look a little like this:
The top edit box needs to contain the path of the Cygwin directory - here c:\cygwin. Set this to point to your installation of Cygwin if you have it. The next edit box should point to the root directory of MingW - here c:\mingw. Set this if you have installed MingW. The "Path to gnumex file utilities" edit box sets the directory with the gnumex files (default - the current working directory). There is also an edit box for the name of the options bat file to be created. You might want to leave this as the default, which is Matlab's default mexopts location for your system or account.
Note also there is a list box for selecting Mingw or Cygwin, or the hybrid Cygwin/mingw compiling/linking:
If you want to use Cygwin compiles, choose the Cygwin option in this list box, and make sure the top (Cygwin root path) box is set to your Cygwin root directory. If you want to use Mingw, select the Mingw option in this list box, and check you have the right "Mingw root path" set. Choose the Cygwin/mingw option for Cygwin/mingw hybrid compiles; this option uses the "Cygwin root path" directory.
A second list box selects whether the opt file is for creating mex files (dlls), or standalone Matlab engine exe files. The default is Mex dll. The third box specifies the language for the compile (C/C++ or fortran). There is also a list box selecting Safe or Quick compiles; this has an associated precompiled library directory edit box. For the moment, leave the list box at it's default value. See Tip 3 for more details on Quick compiles. Lastly, you have the option to compile for a the various pentium chips; see the section on optimized compiles for more details; for the moment leave this option as "All".
After you have set the directories correctly, you may want to save this configuration, using the File-Save config menu option. When it starts up, the gnumex script will look for a default configuration file called gnumexcfg.mat in the same directory as the gnumex.m file, so you could save the file in this directory to get these same options on startup.
When the directories are as you wish, click on the Make opts button at the bottom of the figure, or choose the Make opts file option from the File menu of the figure. The script creates the bat file you specified.
The next thing to do is try a test compile. Before trying, a quick note about mex files compiled using Cygwin linking. If you run a mex file created with Cygwin, then the mex file (which will be a .dll) will need to be able to call functions in the cygwin1.dll, so this will need to be somewhere on the Windows path when the mex file runs. If it isn't, then when you run the mex file, you will get an error message like:
Error loading cygwin1.dll from c:\gnumex\yprime.dll. Error loading c:\gnumex\yprime.dll. ??? Invalid MEX-fileSo, if you are using Cygwin compiles, either arrange to put the cygwin1.dll on the standard path (see above), or run matlab from a Cygnus bash shell, to achieve the same effect.
You should now be able to try a mex file compile. At the Matlab >> prompt, type
mex -f mexopts.bat c:\progra~1\matlab\extern\examples\mex\yprime.cWhere "c:\progra~1\matlab" is your Matlab root directory, and mexopts.bat is the name of the file you have just created in the current working directory.
Type "which yprime" to check that you do indeed have a new "yprime.dll" in your current directory. Check the function by calling it with "yprime(1, 1:4)". You should get:
ans = 2.0000 8.9685 4.0000 -1.0947
With luck you are now up and running. If you want to make gcc your default mex compiler, copy the options file you have just created to overwrite the current default options file (see which this is with "mex -v"). If there is no default file listed by "mex -v", copy the file to mexopts.bat in the Matlab bin directory.
For engine / mat file compiles, instead of mex file compiles, just create an opt file with "Engine exe" selected in the the "Generate mex dll or engine exe?" list box:
You might want to use a different file name for the engine opt file - say engopts.bat.
Below are a couple of optional extra tips to configure your system.
-O3 -mcpu=pentium -malign-double -fno-exceptionswhich are all relatively benign. However, you may well get considerably greater speed improvements by adding the following flag:
-ffast-mathThis option sacrifices some input checking for faster floating point maths - and is in fact part of the standard (-O2) optimization for Microsoft Visual C++. However, to quote from the gcc documenatation: "This option allows GCC to violate some ANSI or IEEE rules and/or specifications in the interest of optimizing code for speed. For example, it allows the compiler to assume arguments to the sqrt function are non-negative numbers and that no floating-point values are NaNs. This option should never be turned on by any `-O' option since it can result in incorrect output for programs which depend on an exact implementation of IEEE or ANSI rules/specifications for math functions."
Note also that you may get major gains in speed from optimizing for a particular processor. You can use the "Processor to compile for" list box in the gnumex window to choose other processors to compile for. Note that the default "All" option here will work for any cpu (after a 486), but - for example - the pentium 3 option will only run on a pentium 3 or higher.
The pentium 4 has particularly fast floating point instructions which can be enabled with the "Pentium 4" option in the list box. This has the advantage of avoiding a very nasty slowdown for the Pentium 4 when it encounters NaN values. See a pentium 4 compilation page for more details.
and create a new opts.bat file. Then try:
mex -f mexopts.bat c:\progra~1\matlab\extern\examples\mex\yprimefg.f c:\progra~1\matlab\extern\examples\mex\yprimef.fFollowed by "yprimefg(1, 1:4)" at the matlab prompt. You should get the same answer as above.
mex myfile.c c:/matlab6p5/extern/lib/win32/microsoft/msvc60/libmwlapack.libYou may on occasion want to link a c file to a fortran object file, which then links to the ATLAS routines; in this case, compile the fortran file with the "-fno-underscoring" flag; e.g - outside matlab:
g77 -fno-underscoring -c my_fortran_file.fThen, inside matlab:
mex myfile.c my_fortran_file.o c:/matlab6p5/extern/lib/win32/microsoft/msvc60/libmwlapack.lib
/usr/lib/gcc-lib/i686-pc-cygwin/3.3.1/../../../../i686-pc-cygwin/bin/ld: warning: cannot find entry symbol _WinMainCRTStartup; defaulting to 00401000It may be harmless; I would be pleased to hear from anyone with feedback on this.
A second problem is that mex dll files compiled with cygwin can crash matlab if reloaded. You can reproduce this problem thus:
>> yprime >> clear yprime >> yprimewhere yprime.dll has been compiled with cygwin.dll linking. This appears to be a problem with dynamic cygwin.dll loading and unloading.
To call the mex scripts, or start Matlab, from a Cygwin bash or 9x/NT console window, you will need to put the Matlab bin directory on your path. If you will just want to call mex from the Cygwin bash shell, then you can add the matlab \bin directory path to your cygwin.bat startup file, which is in your Cygwin directory (default c:\Cygwin). Edit the line:
SET PATH=c:\Cygwin\bin;%PATH%
to read:
SET PATH=c:\Cygwin\bin;c:\progra~1\matlab\bin;%PATH%
where c:\progra~1\matlab is your Matlab root directory. If you want to call Matlab or mex from the NT/9x console prompt, as well as bash, then add the c:\progra~1\matlab\bin (or similar) to the PATH statement in your autoexec.bat file (for Windows 9x), or add it to your path variable using the Control panel -> System -> Environment tab in NT. In NT you might set the variable PATH in your User Variables settings to;
c:\progra~1\matlab\bin;%PATH%
In its default configuration, the Cygwin bash shell will not recognize "mex" as being a command. To run the mex compiler from bash you will need to type "mex.bat <file.c>", where <file.c> is the file you want to compile. The ".bat" extension tells bash that it should run a DOS shell to start up mex.bat. You can automate this by setting an alias within bash. To do this automatically you need to get bash to read a startup configuration file when it runs. If you do not already have one, then create a file called .bashrc, and into it put the following line:
alias mex="mex.bat"To make bash read this startup file:
Now when you run bash, it should read this file and set the alias for "mex". Don't forget to use Unix pathnames when calling mex from bash, e.g. "mex c:/progra~1/matlab/extern/examples/mex/yprime.c"
As the scripts are set up by default in versions of matlab before version 6, the mex file compile routines can be slow. The slowness was because the scripts emulate the behaviour of the mex file compilation with other compilers, by re-creating libraries from the matlab.exe and dll files, for the mex or engine .exe files to link against. These libraries are created every time a mex file is linked, and this process can be slow. If you are only running one compile at a time, the library creation is usually not necessary, as the libraries are the same for each compilation, as long as the matlab.exe main executable and its .dlls are the same. Of course they are always the same unless you have updated your Matlab installation, so a shortcut is to compile these libraries once only, and store them for all subsequent mex file compiles. This is how library linking is done for matlab 6; if you have this version, the quick compile option should be the default. If you want use quick compilation, then follow the instructions below:
Set the precompiled directory to, say, c:\gnumex\precomp. Save the opts bat file with the Make opts button, of menu option. This will create the appropriate opts bat file, and run a script that creates the precompiled libraries in the specified directory. Mex file compiles with this opts bat file should be rather faster than with the safer standard mode.
With this setup, you may run into difficulties with more than one Matlab mex compilation process running at the same time, in which case you can return to safe mode.
>> gnumex usagefor a list of options. Just as a taster, you can use:
>> gnumex mingwto set the default compiles to use gnumex with mingw compiles;
>> gnumex cygwin engto set up cygwin engine (exe) file compilation, and
>> gnumex no-cygwin eng fortran optfile=test.batto write an options file "test.bat" in the current directory, which has settings for making fortran engine files using cygwin/mingw compilation.
mex -v -f mexopts.bat c:\progra~1\matlab\extern\examples\mex\yprime.c(see above), and a copy of the options file created by the gnumex routines - here "mexopts.bat" - all zipped up please. We also need to know your version of matlab, which version of Mingw/Cygwin you are using, and the Windows version.
I hope this page has been useful. Please let me know if you have any comments on this page, or any problems with the installation, and I'll try and update these instructions accordingly.
Happy mexxing.
Many thanks to:
Ton Van Overbeek, who wrote the original scripts and .bat files and to:
Mark Levedahl
Lars Gregerson
Christian Merkwirth
and to:
Mumit Khan, for helpful discussion, and his contributions to gcc,
mingw, dllwrap, which made the whole thing work.
Matthew Brett 3/5/2000, 10/7/2001
Last Refreshed: Fri Aug 12 14:54:38 PDT 2005