ocaml_mingw_port

Introduction

OCaml MinGW port using msys is not officially supported, in fact it is officially not supported, README.win32 stating:

 Do *not* install the standalone distribution of MinGW, nor the
 companion MSYS tools: these have problems with long command lines.
 Instead, use the version of MinGW that is installed along with Cygwin.

However MinGW provides a good UNIX to Windows translation and many of the features missing from the ocaml mingw port are in fact available, the problem being configure scripts which are not adapted.
This page intends to provide updates, ideas and patchs for people willing to help in improving this port.

./configure - not complete

First, you ought to use a clean source so download ocaml sources, unpack them. All paths in this section will be relative to the folder where you have done this.

echo "TOOLCHAIN=cc" >> Makefile

and insert the following after it:

echo "MAKEREC=\$(MAKE) -f Makefile.nt " >> Makefile
echo "MAKECMD=\$(MAKE)" >> Makefile

In the same file, find

case "$arch,$model,$system" in

and after this case structure, add:

if MACHTYPE=i686-pc-msys; then
 aspp='gcc'; asppflags='-c -DSYS_$(SYSTEM)';
fi
MKDLL=$(BYTECC) -shared -o $(1) -Wl,--out-implib,$(2) $(3)

In the same file, change the OTHERLIBRARIES line to:

win32unix systhreads str num win32graph dynlink bigarray

(you may append labltk if you have it but by default it's not present) Finally, add:

SO=s.o
DO=d.o
#define OCAML_STDLIB_DIR "/some/path"
#define HAS_UNISTD

add these:

#undef BSD_SIGNALS
#define HAS_STRERROR
#define HAS_SOCKETS
#define HAS_GETHOSTNAME

and set this because even with mingw, this is still win32:

#define OCAML_OS_TYPE "Win32"
cp /mingw/include/unistd.h /usr/include

pthreads

MinGW lets build pthread-enabled apps thanks to pthreads-win32. However the code needed to use (recent?) versions of pthreads under Windows require dllimport which is certainly not the case under Unix.

Once compilation is done, type

 cp libpthreadGC2.a /mingw/lib/ 
 cp libpthreadGC2.a /mingw/lib/libpthread.a
 cp pthread.h sched.h /mingw/include/ 
 cp config/auto-aux/hasgot config/auto-aux/hasgot_pthreads

and edit hasgot_pthreads. Replace

 (echo "main() {"
  for f in $*; do echo "  $f();"; done
  echo "}") >> hasgot.c

with

 (echo "__attribute__((dllexport)) PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self(void);
  main() {"
  for f in $*; do echo "  $f();"; done
  echo "}") >> hasgot.c
 pthread_caml_link="-cclib -pthread"

This is located inside a case structure. Add a *-pc-mingw32 entry to make it:

   case "$host" in
     *-*-solaris*)  pthread_link="-lpthread -lposix4"
                    pthread_caml_link="-cclib -lpthread -cclib -lposix4";;
     *-*-freebsd*)  pthread_link="-pthread"
                    pthread_caml_link="-cclib -pthread";;
     *-*-openbsd*)  pthread_link="-pthread"
                    pthread_caml_link="-cclib -pthread";;
     *-pc-mingw32*) pthread_link="-lpthread -lws2_32"
                    pthread_caml_link="-cclib -lpthread";;
     *)             pthread_link="-lpthread"
                    pthread_caml_link="-cclib -lpthread";;
   esac
 if ./hasgot -i pthread.h $pthread_link pthread_self; then

to make it:

 if ./hasgot_pthreads -i pthread.h $pthread_link pthread_self; then

General rules and hints

Linking errors : "undefined reference to foo" and others

-lws2_32

Many, many, many (C) functions under win32 need to be linked with libws2_32.a so one must pass -lws2_32 (within the call for the compiler usually).
Any function which has a relation with sockets, even the weakest one is likely to require this.
A more precise list can be found on this Wine page in the "exports" section (you can't miss it).

_imp_, dllimport/export, --enable-auto-import

If you get undefined references to _imp_* functions then there is a dllimport problem. Lots of details can be found on this GNU binutils page.