From: mlevedahl AT fallschurch DOT esys DOT com (Mark Levedahl) Subject: Re: cygwin compiled DLLs 19 Dec 1998 15:39:56 -0800 Message-ID: <367C044E.21FCED5.cygnus.gnu-win32@fallschurch.esys.com> References: <367A77D3 DOT DE81DD64 AT fallschurch DOT esys DOT com> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit To: Charles Wilson Cc: gnu-win32 AT cygnus DOT com 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 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 # '. 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".