Mail Archives: cygwin/1998/12/19/15:39:56
Charles Wilson wrote:
> I had no idea this was possible. This is great! Please either post it to the
> list, or check into uploading it to the ftp.franken.de repository.
>
> Chuck Wilson
>
>
Ok, here it is. A couple of caveats:
1) I have only ever used this script to assemble multiple .c files together: c++
source might be useable, but I've never tried (and see note 2). Also, the script
expects only source files, no precompiled objects or other libraries. You could
easily modify for that.
2) MATLAB controls all memory allocation for its session, including any MEX
files. Hence, all memory allocation must go through mxMalloc/mxCalloc/MxFree.
Directly accessing malloc/free is not allowed. Thus, any library functions that
allocate memory must be recompiled using these memory allocation routines. (This
explains why opendir fails). I suspect c++ new/delete would need overloads as
well.
3) That said, I have had success linking to both the cygwin and mscrt libraries
(the latter through -mno-cygwin).
Mark Levedahl
#! /bin/bash
# compile and link a MATLAB MEX file (relocatable DLL)
#
# required import libraries
IMPDEFS="matlab.exe libmx.dll"
# ***Fill in your path to libcygwin.a here (with no trailing slash)***
LIBPATH=${CYGFS}/H-i586-cygwin32/i586-cygwin32/lib
# ***Fill in your path to the matlab 5 root here (with no trailing slash)***
MATLAB=/app/matlab
# ***Fill in your path to place to store .def files generated by this script
LIBMEX=$MATLAB/bin/implibs
# check for arguments
if [ $# -lt 1 ]; then
echo "usage: cmex [-cig5] source"
exit
fi
debug=0
inline=0
type=-mno-cygwin
arch=i686
while getopts cig5? v; do
if [ "$v" == "?" ]; then
echo "usage: cmex [-cig5] source"
echo " c : link to cygwin1.dll (default:mingw)"
echo " i : inline array access"
echo " g : include debug info"
echo " 5 : optimize for pentium (default:686)"
exit
else
case $v in
(g) debug=1;;
(i) inline=1;;
(5) arch=i586;;
(c) type= ;;
esac
fi
done
while [ $OPTIND -gt 1 ]; do
shift
OPTIND=$(($OPTIND - 1))
done
# debug or what?
if [ $debug -eq 1 ]; then
gccopts="-Wall -g $type"
else
gccopts="-Wall -O6 $type -march=$arch -ffast-math -fstrict-aliasing
-malign-double"
fi
# inline array access?
if [ $inline -eq 0 ]; then
rcopts=
else
rcopts="--define ARRAY_ACCESS_INLINING"
gccopts="$gccopts -DARRAY_ACCESS_INLINING"
fi
# source file name(s)
source=$*
base=${1%.*}
objs=${*//%.*/.o}
# Compile source file(s):
echo "windres $rcopts -i $MATLAB/extern/include/mexversion.rc -o mexversion.o"
windres $rcopts -i $MATLAB/extern/include/mexversion.rc -o mexversion.o || exit
echo "gcc -c $gccopts -DMATLAB_MEX_FILE -I$MATLAB/extern/include ${source}"
gcc -c $gccopts -DMATLAB_MEX_FILE -I$MATLAB/extern/include ${source} || exit
# Create fixup.o which is needed to terminate the
# import list and the relocation section in the dll.
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");
/* Next one is needed to properly terminate the .reloc section in the dll
*/
asm(".section .reloc\n" ".long 0,8");
EOF
gcc -c $gccopts 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 $gccopts init.c
# create import libraries if needed...
# Note:
# Dlltool 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 the .def file starts with the line 'EXPORTS'
IMPLIBS=
if [ ! -d $LIBMEX ];then
mkdir -p $LIBMEX
fi
for libname in ${IMPDEFS}; do
if [ ! -f $LIBMEX/${libname%.*}.a ];then
cd $MATLAB/bin
echo "Creating $libname import library..."
tail +2l $MATLAB/extern/include/matlab.def > temp.def
echo dlltool --def temp.def --dllname $libname --output-lib
$LIBMEX/${libname%.*}.a
dlltool --def temp.def --dllname $libname --output-lib $LIBMEX/${libname%.*}.a
|| exit
rm temp.def
cd -
else
echo "Will use existing import library $LIBMEX/${libname%.*}.a"
fi
IMPLIBS="${IMPLIBS} $LIBMEX/${libname%.*}.a"
done
# Make .def file:
echo EXPORTS > ${base}.def
echo mexFunction >> ${base}.def
# Link DLL.
echo 'Linking DLL...'
dllwrap -o ${base}.dll --def ${base}.def --entry _dll_entry AT 12 \
${objs} init.o fixup.o mexversion.o ${IMPLIBS} $LIBPATH/libcygwin.a
# Clean up
rm ${base}.o init.c init.o fixup.c fixup.o mexversion.o ${base}.def
-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request AT cygnus DOT com" with one line of text: "help".
- Raw text -