Subject: How to use MEX.BAT and the GNU Win32 tools in MATLAB 5
From: [email-masked] (Ton van Overbeek)

9 Jul 1997 08:15:20 -0700
Approved: [email-masked]
Distribution: cygnus
Message-ID: <[email-masked]>
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="------------15FB748359E2B6001CFBAE39"
X-Mailer: Mozilla 3.01 (X11; I; SunOS 4.1.3_U1 sun4m)
Original-Cc: [email-masked], [email-masked], [email-masked]
Original-Sender: [email-masked]

This is a multi-part message in MIME format.

--------------15FB748359E2B6001CFBAE39
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

As promised here my setup to use the GNU Win32 tools from within
Matlab with the mex command (using mex.m and MEX.BAT).
The following things have to be in place on your Win95/WinNT system:
- The GNU Win32 tools have to be installed properly.
  I have used the b18 release.
  See http://www.cygnus.com/misc/gnu-win32
- The GNU tools have to be on the DOS path.
- Also the %MATLAB%\bin directory (where matlab.exe and mex.bat live)
  has to be on the DOS path. Otherwise mex.m cannot start mex.bat.
- You will probably need the patched version of cygwin.dll and
  libcygwin.a from Sergey Okhapkin. I had to use those for my initial
  (non-Matlab) DLL builds and never went back to the ones supplied
  with the Cygnus b18 release.
  Alternatively you might want to try to use the minimalist GNU Win32
  system which does not need cygwin.dll. I have not tried that.
  See http://www/fu.is.saga-u.ac.jp/~colin/gcc.html.
- You will also need peclean.exe to cleanup the DLL's produced by
  the linker. GNU Win32's ld leaves cruft in the unused part at the
  end of a section (especially on Win95). The DLL section with 
  relocation information is especially sensitive for this. If there is
  non-zero cruft immeidately after the usefull part of the .reloc
  section the DLL will not load. This program can be found in the
  gnu-win32 mailing list archive:
   http://www.cygnus.com/ml/gnu-win32/1997-Jul/0047.html.

When this is done, put all the *.sh and *.bat files attached to this
message in %MATLAB%\bin and you should be set to go.

I have successfully compiled and run the yprime, explore and mextest1
examples from %MATLAB%\extern\examples\mex.

Also the MAT and engine examples in %MATLAB%\extern\examples\eng_mat
compiled and ran successfully using the gw32engmatopts.bat options
file. Note that engwindemo.c has a nasty bug. buffer is declared as
char buffer[256] while later engOutputBuffer wants to use a size of
300. This will write past the end of the declared buffer. Result:
crash, access violation, ... So before compiling engwindemo.c increase
the declared size of buffer to 300.
Also both in engdemo.c and engwindemo.c the buffer should be zeroed
before each use to ensure a proper zero termination when the buffer
is filled by Matlab.

I hope this information is usefull to some of you who want to use the
GNU-Win32 tools for MEX file development.

Ton van Overbeek, [email-masked]
European Space Agency, ESTEC, Noordwijk, The Netherlands

--------------15FB748359E2B6001CFBAE39
Content-Type: text/plain; charset=us-ascii; name="gw32opts.bat"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="gw32opts.bat"

@echo off
rem GW32OPTS.BAT
rem
rem    Compile and link options used for building MEX-files with
rem    the GNU Win32 tools
rem
rem ********************************************************************
rem General parameters
rem ********************************************************************
set MATLAB=c:\win32app\matlab5
set GNUWIN32=c:\gnuwin32\b18
rem set PATH=%PATH%
rem set INCLUDE=%INCLUDE%
set LIB=%GNUWIN32%\H-i386-cygwin32\i386-cygwin32\lib
set PECLEAN=C:/gnuwin32/usr/local/bin/peclean.exe

rem ********************************************************************
rem Compiler parameters
rem ********************************************************************
set COMPILER=bash compile.sh
set COMPFLAGS=-c -DMATLAB_MEX_FILE
set OPTIMFLAGS=-O2
set DEBUGFLAGS=-g

rem ********************************************************************
rem Library creation command
rem ********************************************************************
set PRELINK_CMDS=bash prelink.sh %MATLAB%\extern\include\matlab.def %LIB_NAME%1.lib
set PRELINK_CMDS=%PRELINK_CMDS%;bash prelinkmex.sh

rem ********************************************************************
rem Linker parameters
rem ********************************************************************
set LINKER=bash linkmex.sh
set LINKFLAGS=--dll -e _mexFunction
set LINKOPTIMFLAGS=
set LINKDEBUGFLAGS=-g
set LINK_FILE=
set LINK_LIB= 
set NAME_OUTPUT=-o %MEX_NAME%.dll

--------------15FB748359E2B6001CFBAE39
Content-Type: text/plain; charset=us-ascii; name="gw32engmatopts.bat"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="gw32engmatopts.bat"

@echo off
rem GW32ENGMATOPTS.BAT
rem
rem    Compile and link options used for building standalone engine or
rem    MAT programs with the GNU Win32 tools
rem
rem ********************************************************************
rem General parameters
rem ********************************************************************
set MATLAB=c:\win32app\matlab5
set GNUWIN32=c:\gnuwin32\b18
rem set PATH=%PATH%
rem set INCLUDE=%INCLUDE%
set LIB=%GNUWIN32%\H-i386-cygwin32\i386-cygwin32\lib

rem ********************************************************************
rem Compiler parameters
rem ********************************************************************
set COMPILER=bash compile.sh
set COMPFLAGS=-c -DMATLAB_MEX_FILE
set OPTIMFLAGS=-O2
set DEBUGFLAGS=-g

rem ********************************************************************
rem Library creation command
rem ********************************************************************
set PRELINK_CMDS=bash prelink.sh %MATLAB%\extern\include\libmx.def %LIB_NAME%1.lib
set PRELINK_CMDS=%PRELINK_CMDS%;bash prelink.sh %MATLAB%\extern\include\libeng.def %LIB_NAME%2.lib
set PRELINK_CMDS=%PRELINK_CMDS%;bash prelink.sh %MATLAB%\extern\include\libmat.def %LIB_NAME%3.lib

rem ********************************************************************
rem Linker parameters
rem ********************************************************************
set LINKER=bash linkengmat.sh
set LINKFLAGS=%LIB_NAME%1.lib %LIB_NAME%2.lib %LIB_NAME%3.lib 
set LINKOPTIMFLAGS=
set LINKDEBUGFLAGS=-g
set LINK_FILE=
set LINK_LIB= 
set NAME_OUTPUT=-o %MEX_NAME%.exe

--------------15FB748359E2B6001CFBAE39
Content-Type: text/plain; charset=us-ascii; name="compile.sh"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="compile.sh"

# compile.sh
# 
# mex.bat insists on calling compiler output .obj

# compile -> .o file
gcc $@

# rename .o to .obj
mv ${_%.c}.o ${_%.c}.obj

--------------15FB748359E2B6001CFBAE39
Content-Type: text/plain; charset=us-ascii; name="prelink.sh"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="prelink.sh"

# prelink.sh
#
# This script creates an import library ($2) from a
# .def file ($1).

# Dlltool in the b18 release does not like .def files to start
# with a line 'LIBRARY <libname>'.
# Therefore this workaround: 
#  extract library name from line 1 into variable libname
#  and feed dlltool with a .def file with the 1st line stripped
#  so it starts with the line 'EXPORTS'
libname=`head -1 $1|sed -e 's/^LIBRARY //'`
echo 'Creating import library for ' $libname ' ...'
tail +2l $1 > temp.def
dlltool --def temp.def --dllname $libname --output-lib $2
rm temp.def

--------------15FB748359E2B6001CFBAE39
Content-Type: text/plain; charset=us-ascii; name="prelinkmex.sh"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="prelinkmex.sh"

# prelinkmex.sh
#
# This script creates the .def file and various object files
# needed to create a DLL with the GNU Win32 tools

# Create .def file for our MEX file
cat > mex.def << EOF
EXPORTS
mexFunction
EOF

# Create fixup.o which is needed to terminate the import list.
cat > fixup.c << EOF
/* Copied from winsup/dcrt0.cc in the cygwin32 source distribution. */
	asm(".section .idata\$3\n" ".long 0,0,0,0, 0,0,0,0");
EOF
gcc -c fixup.c

# Create a very minimalist startup routine for the dll.
# C copy of winsup/init.cc in the cygwin32 source distribution.
cat > init.c << EOF
#include <windows.h>

int WINAPI dll_entry (HANDLE h,
		     DWORD reason,
		     void *ptr)
{
  switch (reason)
    {
    case DLL_PROCESS_ATTACH:
      break;
    case DLL_PROCESS_DETACH:
      break;
    case DLL_THREAD_ATTACH:
      break;
    case DLL_THREAD_DETACH:
      break;
    }
  return 1;
}
EOF
gcc -c init.c

--------------15FB748359E2B6001CFBAE39
Content-Type: text/plain; charset=us-ascii; name="linkmex.sh"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="linkmex.sh"

# linkmex.sh
#
# Link pass 1
ld --base-file mex.base $@ init.o fixup.o ${LIB_NAME}1.lib \
 $LIB/libcygwin.a -e _dll_entry@12
#
# Generate .exp file
dlltool --dllname $MEX_NAME.dll --def mex.def --base-file mex.base \
 --output-exp mex.exp
#
# Link pass 2
ld mex.exp $@ init.o fixup.o ${LIB_NAME}1.lib \
 $LIB/libcygwin.a -e _dll_entry@12
#
# Cleanup
$PECLEAN $MEX_NAME.dll
rm init.c init.o fixup.c fixup.o mex.def mex.exp mex.base

--------------15FB748359E2B6001CFBAE39
Content-Type: text/plain; charset=us-ascii; name="linkengmat.sh"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="linkengmat.sh"

# linkengmat.sh
#
# Script to link MAT and engine programs

gcc $@ ${LIB_NAME}1.lib ${LIB_NAME}2.lib ${LIB_NAME}3.lib -luser32 -lgdi32

# ${LIB_NAME}3.lib is not removed by the perl script in mex.bat
rm ${LIB_NAME}3.lib

--------------15FB748359E2B6001CFBAE39--

-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".