Table of Contents

Compiling Matlab mex files with gcc for Windows

This page is designed to explain how to install the GNU compiler compiler collection (gcc) for Windows, to compile matlab mex and other files. It was originally written for the b20.1 release. The current release (as of August 2004) is cygwin 1.5.10-3.

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.

Mingw and Cygwin

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.

The Gnumex archive: development and credits

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.

Installing Mingw

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.

Installing Cygwin

Warning: cygwin mex files compiled with the current cygwin gcc (3.3) cause matlab to crash. You will need to get hold of an earlier (3.2) version of cygwin gcc for this to work.

Step 1: Install Cygwin

The version that you want is available via the Ptolemy cywgin page. Get the CygwinDevel.exe version from there, and install as described in that page.

Step 2: fix some little installation problems

There are two little gotchas for Cygwin installations that come up with windows 9x. The first is an "Out of environment space" error that can occur when running the bash shell via the cygwin.bat file. If you get this, you can get round it using one of two methods. The first is to increase the environment space for any shell: edit your config.sys file, adding a line like "shell=C:\command.com /e:4096 /p" (if C: is your system drive letter). The second is to edit the memory properties of the cygwin.bat file, which starts up Cygwin bash. Right click on the cygwin.bat file name in Windows Explorer, choose properties from the menu, and the Memory tab in the dialog box. Change the Initial Environment value to 4096K. The second issue that may come up with Windows 9x is that you may have problems running cygwin.bat if you have spaces in the filenames in your PATH variable; on my system this gave me an error message like "Too many parameters; Bad command or file name". If you have this problem then try putting inverted commas round the right hand side of the PATH= line in cygwin.bat (but don't do this in NT...).

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.

For Mingw, or Cygwin: installing the gnumex archive

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.

A little technical aside

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.

Set up Matlab for gcc mex file compilation

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.

A test mex file compilation

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-file
So, 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.c
Where "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.

Optimizing gcc compilation for mex files

(With many thanks to Alberto Martinez). There are a large number of different flags which can be used with gcc to optimize code for speed; these are described in the gcc documentation. The optimization options specified by default in the gnumex package are the following:
-O3 -mcpu=pentium -malign-double -fno-exceptions
which are all relatively benign. However, you may well get considerably greater speed improvements by adding the following flag:
-ffast-math
This 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.

Fortran compilation

The GNU compiler collection includes a Fortran compiler, g77. g77 seems to be able to compile the example mex and engine files for matlab 5.3, 6.1 and 6.3; I would be very glad to hear of any problems with other versions of matlab, or Fortran files. To try the Fortran compilation, select the Fortran option in the Gnumex window:

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.f 
Followed by "yprimefg(1, 1:4)" at the matlab prompt. You should get the same answer as above.

Linking to LAPACK/BLAS libraries

Mex files doing a lot of matrix algebra are likely to benefit from linking to the highly optimized BLAS and LAPACK routines. In matlab 6.0 and higher, these are provided using ATLAS libraries. Linking steps are described in a Mathworks BLAS/LAPACK help page. For gcc, you simply follow the instructions on that page, but use the Microsoft MSVC++ import libraries to link to; e.g, from the matlab prompt:
mex myfile.c c:/matlab6p5/extern/lib/win32/microsoft/msvc60/libmwlapack.lib
You 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.f  
Then, inside matlab:
mex myfile.c my_fortran_file.o c:/matlab6p5/extern/lib/win32/microsoft/msvc60/libmwlapack.lib

Using autotools with gnumex

Christopher Hulbert has kindly written a page on using GNU autotools with gnumex. GNU autotools (autoconf and automake) allow you to script platform independent compilation which is often useful for larger projects.

Debugging mex files with gdb

Please see this helpful text file by Mark Levedahl.

Current problems

The latest version of gnumex outputs a warning when compiling engine (exe) files with cygwin; this looks something like:
/usr/lib/gcc-lib/i686-pc-cygwin/3.3.1/../../../../i686-pc-cygwin/bin/ld: warning: cannot find entry symbol _WinMainCRTStartup; defaulting to 00401000
It 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
>> yprime
where yprime.dll has been compiled with cygwin.dll linking. This appears to be a problem with dynamic cygwin.dll loading and unloading.

Tip 1: Put the Matlab bin directory on your path

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%

Tip 2: If using Cygwin: Set up bash to call mex.bat smoothly

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:

  1. set the environment variable "HOME" to some directory, such as "c:\home\myname", where you want to store your startup file. Do this using the Control panel -> System -> Environment tab in NT, or by editing your autoexec.bat file in Windows 9x.
  2. Copy the .bashrc file to the directory named in HOME.

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"

Tip 3: Faster mex file compiling

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:

  1. Make a directory to store the compiled libraries, say c:\gnumex\precomp.
  2. Run the gnumex.m program, and choose the Quick option from the Compile type list box:

    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.

  3. If for any reason you update your Matlab installation with a new matlab.exe or dlls, then don't forget to rerun the "gnumex" bat creation program, to update the libraries.

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.

Tip 4: setting options from the command line

Thus far I have described the gnumex GUI. You can also use gnumex from the command line. You should first make sure you have set the various directories correctly, and have saved the configuration, as described above. After this, you can very quickly change your settings from the command line. Type:
>> gnumex usage
for a list of options. Just as a taster, you can use:
>> gnumex mingw
to set the default compiles to use gnumex with mingw compiles;
>> gnumex cygwin eng
to set up cygwin engine (exe) file compilation, and
>> gnumex no-cygwin eng fortran optfile=test.bat
to write an options file "test.bat" in the current directory, which has settings for making fortran engine files using cygwin/mingw compilation.

Help

If you have a problem with the installation of this package, please first check you have followed the instructions above carefully. If you are still in difficulty, consider mailing the gnumex mailing list; list archives and instructions for posting are available via the gnumex users mailing list page. There is also a gnumex mailing list archive If you want support with an installation problem, it will be useful if you can send details, including the output of
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.

And finally

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

SourceForge.net Logo

Last Refreshed: Fri Aug 12 14:54:38 PDT 2005