Beginnings of an OCaml cross-compiler.
authorRichard W.M. Jones <rjones@redhat.com>
Sat, 15 Nov 2008 18:44:09 +0000 (18:44 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Sat, 15 Nov 2008 18:44:09 +0000 (18:44 +0000)
ocaml/Makefile-fedora-mingw.in [new file with mode: 0644]
ocaml/mingw32-ocaml-3.11.0+beta1-combined-Makefile.patch [new file with mode: 0644]
ocaml/mingw32-ocaml-3.11.0+beta1-disable-cmxs.patch [new file with mode: 0644]
ocaml/mingw32-ocaml-3.11.0+beta1-filename-win32-dirsep.patch [new file with mode: 0644]
ocaml/mingw32-ocaml-3.11.0+beta1-i386-profiling.patch [new file with mode: 0644]
ocaml/mingw32-ocaml-3.11.0+beta1-no-stdlib-dir.patch [new file with mode: 0644]
ocaml/mingw32-ocaml-3.11.0+beta1-win32-fixes.patch [new file with mode: 0644]
ocaml/mingw32-ocaml-3.11.0+beta1-win32unix-path.patch [new file with mode: 0644]
ocaml/mingw32-ocaml.spec

diff --git a/ocaml/Makefile-fedora-mingw.in b/ocaml/Makefile-fedora-mingw.in
new file mode 100644 (file)
index 0000000..f056246
--- /dev/null
@@ -0,0 +1,79 @@
+PREFIX=@prefix@
+BINDIR=@bindir@
+LIBDIR=@libdir@/i686-pc-mingw32-ocaml
+STUBLIBDIR=$(LIBDIR)/stublibs
+MANDIR=$(PREFIX)/man
+MANEXT=1
+RANLIB=i686-pc-mingw32-ranlib
+RANLIBCMD=i686-pc-mingw32-ranlib
+SHARPBANGSCRIPTS=true
+BNG_ARCH=i386
+BNG_ASM_LEVEL=1
+PTHREAD_LINK=
+X11_INCLUDES=
+X11_LINK=
+DBM_INCLUDES=
+DBM_LINK=
+TK_DEFS=
+TK_LINK=
+BYTECC=i686-pc-mingw32-gcc
+BYTECCCOMPOPTS=-O -mms-bitfields -Wall -Wno-unused
+BYTECCLINKOPTS=
+BYTECCLIBS=
+BYTECCRPATH=
+EXE=
+SUPPORTS_SHARED_LIBRARIES=true
+SHAREDCCCOMPOPTS=-fPIC
+MKSHAREDLIBRPATH=
+NATDYNLINKOPTS=-Wl,-E
+SYSLIB=-l$(1)
+#ml let syslib x = "-l"^x;;
+
+### How to build a static library
+MKLIB=i686-pc-mingw32-ar rcs $(1) $(2)
+#ml let mklib out files opts = Printf.sprintf "ar rc %s %s %s; ranlib %s" out opts files out;;
+ARCH=i386
+MODEL=default
+SYSTEM=mingw
+NATIVECC=i686-pc-mingw32-gcc
+NATIVECCCOMPOPTS=-O -mms-bitfields -Wall -Wno-unused
+NATIVECCPROFOPTS=-pg
+NATIVECCLINKOPTS=
+NATIVECCRPATH=
+NATIVECCLIBS=
+ASM=i686-pc-mingw32-as
+ASPP=i686-pc-mingw32-gcc -c
+ASPPPROFFLAGS=-DPROFILING
+PROFILING=prof
+DYNLINKOPTS=-ldl
+OTHERLIBRARIES=win32unix str num dynlink bigarray systhreads win32graph
+DEBUGGER=ocamldebugger
+CC_PROFILE=-pg
+SYSTHREAD_SUPPORT=true
+PARTIALLD=i686-pc-mingw32-ld -r
+PACKLD=$(PARTIALLD) $(NATIVECCLINKOPTS) -o 
+DLLCCCOMPOPTS=
+IFLEXDIR=-I@libdir@/flexdll
+O=o
+A=a
+SO=dll
+EXT_OBJ=.o
+EXT_ASM=.s
+EXT_LIB=.a
+EXT_DLL=.dll
+EXTRALIBS=
+CCOMPTYPE=cc
+TOOLCHAIN=cc
+CMXS=cmxs
+FLEXLINK=flexlink -chain mingw
+MKEXE=$(FLEXLINK) -exe
+MKDLL=$(FLEXLINK)
+MKMAINDLL=$(FLEXLINK) -maindll
+
+# Build compiler for cross-compilation.
+BUILD_MKEXE=gcc
+BUILD_RANLIB=ranlib
+BUILD_MKDLL=gcc -shared
+BUILD_CC=gcc
+BUILD_CCLIBS=-lm
+BUILD_CFLAGS=
\ No newline at end of file
diff --git a/ocaml/mingw32-ocaml-3.11.0+beta1-combined-Makefile.patch b/ocaml/mingw32-ocaml-3.11.0+beta1-combined-Makefile.patch
new file mode 100644 (file)
index 0000000..2a2827a
--- /dev/null
@@ -0,0 +1,160 @@
+OCaml sources uses separate Makefile and Makefile.nt in each directory,
+which is a pain when cross-compiling.  Instead of that, it's better to
+combine all objects into one Makefile, and make sure the source is
+defended by #ifdef/#ifndef WIN32 ... #endif, around the whole files as
+necessary.
+
+diff -urN ocaml-3.11.0+beta1.orig/asmrun/Makefile ocaml-3.11.0+beta1.mingw/asmrun/Makefile
+--- ocaml-3.11.0+beta1.orig/asmrun/Makefile    2007-11-15 13:21:15.000000000 +0000
++++ ocaml-3.11.0+beta1.mingw/asmrun/Makefile   2008-11-15 14:43:50.000000000 +0000
+@@ -26,7 +26,7 @@
+   misc.o freelist.o major_gc.o minor_gc.o memory.o alloc.o compare.o ints.o \
+   floats.o str.o array.o io.o extern.o intern.o hash.o sys.o parsing.o \
+   gc_ctrl.o terminfo.o md5.o obj.o lexing.o printexc.o callback.o weak.o \
+-  compact.o finalise.o custom.o unix.o backtrace.o natdynlink.o
++  compact.o finalise.o custom.o unix.o win32.o backtrace.o natdynlink.o
+ ASMOBJS=$(ARCH).o
+@@ -138,6 +138,8 @@
+       ln -s ../byterun/globroots.c globroots.c
+ unix.c: ../byterun/unix.c
+       ln -s ../byterun/unix.c unix.c
++win32.c: ../byterun/win32.c
++      ln -s ../byterun/win32.c win32.c
+ dynlink.c: ../byterun/dynlink.c
+       ln -s ../byterun/dynlink.c dynlink.c
+ signals.c: ../byterun/signals.c
+@@ -146,7 +148,7 @@
+ LINKEDFILES=misc.c freelist.c major_gc.c minor_gc.c memory.c alloc.c array.c \
+   compare.c ints.c floats.c str.c io.c extern.c intern.c hash.c sys.c \
+   parsing.c gc_ctrl.c terminfo.c md5.c obj.c lexing.c printexc.c callback.c \
+-  weak.c compact.c finalise.c meta.c custom.c main.c globroots.c unix.c \
++  weak.c compact.c finalise.c meta.c custom.c main.c globroots.c unix.c win32.c \
+   dynlink.c signals.c
+ clean::
+diff --exclude _build -urN ocaml-3.11.0+beta1.orig/byterun/Makefile.common ocaml-3.11.0+beta1.mingw/byterun/Makefile.common
+--- ocaml-3.11.0+beta1.orig/byterun/Makefile.common    2008-09-10 06:51:11.000000000 +0100
++++ ocaml-3.11.0+beta1.mingw/byterun/Makefile.common   2008-11-15 15:47:05.000000000 +0000
+@@ -24,7 +24,7 @@
+   compare.o ints.o floats.o str.o array.o io.o extern.o intern.o \
+   hash.o sys.o meta.o parsing.o gc_ctrl.o terminfo.o md5.o obj.o \
+   lexing.o callback.o debugger.o weak.o compact.o finalise.o custom.o \
+-  dynlink.o
++  dynlink.o win32.o
+ PRIMS=\
+   alloc.c array.c compare.c extern.c floats.c gc_ctrl.c hash.c \
+diff --exclude _build -urN ocaml-3.11.0+beta1.orig/byterun/unix.c ocaml-3.11.0+beta1.mingw/byterun/unix.c
+--- ocaml-3.11.0+beta1.orig/byterun/unix.c     2008-04-22 13:40:14.000000000 +0100
++++ ocaml-3.11.0+beta1.mingw/byterun/unix.c    2008-11-15 14:44:12.000000000 +0000
+@@ -15,6 +15,8 @@
+ /* Unix-specific stuff */
++#ifndef WIN32
++
+ #define _GNU_SOURCE
+            /* Helps finding RTLD_DEFAULT in glibc */
+@@ -320,3 +322,5 @@
+ }
+ #endif
++
++#endif /* !WIN32 */
+diff --exclude _build -urN ocaml-3.11.0+beta1.orig/byterun/win32.c ocaml-3.11.0+beta1.mingw/byterun/win32.c
+--- ocaml-3.11.0+beta1.orig/byterun/win32.c    2008-04-22 13:24:10.000000000 +0100
++++ ocaml-3.11.0+beta1.mingw/byterun/win32.c   2008-11-15 15:50:32.000000000 +0000
+@@ -13,6 +13,8 @@
+ /* $Id: win32.c,v 1.36 2008/04/22 12:24:10 frisch Exp $ */
++#ifdef WIN32
++
+ /* Win32-specific stuff */
+ #include <windows.h>
+@@ -543,3 +564,5 @@
+   seed ^= GetCurrentProcessId();
+   return seed;
+ }
++
++#endif /* WIN32 */
+diff --exclude _build -urN ocaml-3.11.0+beta1.orig/otherlibs/systhreads/Makefile ocaml-3.11.0+beta1.mingw/otherlibs/systhreads/Makefile
+--- ocaml-3.11.0+beta1.orig/otherlibs/systhreads/Makefile      2008-07-15 16:31:32.000000000 +0100
++++ ocaml-3.11.0+beta1.mingw/otherlibs/systhreads/Makefile     2008-11-15 15:51:58.000000000 +0000
+@@ -20,8 +20,8 @@
+ MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib
+ COMPFLAGS=-warn-error A -g
+-BYTECODE_C_OBJS=posix_b.o
+-NATIVECODE_C_OBJS=posix_n.o
++BYTECODE_C_OBJS=posix_b.o win32_b.o
++NATIVECODE_C_OBJS=posix_n.o win32_n.o
+ THREAD_OBJS= thread.cmo mutex.cmo condition.cmo event.cmo threadUnix.cmo
+@@ -39,6 +39,10 @@
+          -c posix.c
+       mv posix.o posix_b.o
++win32_b.$(O): win32.c
++      $(BYTECC) -I ../../byterun $(BYTECCCOMPOPTS) $(CFLAGS) -c win32.c
++      mv win32.$(O) win32_b.$(O)
++
+ # Dynamic linking with -lpthread is risky on many platforms, so
+ # do not create a shared object for libthreadsnat.
+ libthreadsnat.a: $(NATIVECODE_C_OBJS)
+@@ -48,9 +52,13 @@
+       $(NATIVECC) -O -I../../asmrun -I../../byterun $(NATIVECCCOMPOPTS) $(SHAREDCCCOMPOPTS) -DNATIVE_CODE -DTARGET_$(ARCH) -DSYS_$(SYSTEM) -c posix.c
+       mv posix.o posix_n.o
++win32_n.$(O): win32.c
++      $(NATIVECC) -DNATIVE_CODE -O -I../../asmrun -I../../byterun $(NATIVECCCOMPOPTS) -c win32.c
++      mv win32.$(O) win32_n.$(O)
++
+ threads.cma: $(THREAD_OBJS)
+       $(MKLIB) -ocamlc '$(CAMLC)' -o threads $(THREAD_OBJS) \
+-          -cclib -lunix $(PTHREAD_LINK)
++          -cclib -lunix $(PTHREAD_LINK) -lcamlrun
+ # See remark above: force static linking of libthreadsnat.a
+ threads.cmxa: $(THREAD_OBJS:.cmo=.cmx)
+diff --exclude _build -urN ocaml-3.11.0+beta1.orig/otherlibs/systhreads/posix.c ocaml-3.11.0+beta1.mingw/otherlibs/systhreads/posix.c
+--- ocaml-3.11.0+beta1.orig/otherlibs/systhreads/posix.c       2008-09-27 11:46:55.000000000 +0100
++++ ocaml-3.11.0+beta1.mingw/otherlibs/systhreads/posix.c      2008-11-15 15:35:28.000000000 +0000
+@@ -13,6 +13,8 @@
+ /* $Id: posix.c,v 1.58 2008/09/27 10:46:55 xleroy Exp $ */
++#ifndef WIN32
++
+ /* Thread interface for POSIX 1003.1c threads */
+ #include <errno.h>
+@@ -924,3 +926,4 @@
+   raise_sys_error(str);
+ }
++#endif /* !WIN32 */
+diff --exclude _build -urN ocaml-3.11.0+beta1.orig/otherlibs/systhreads/win32.c ocaml-3.11.0+beta1.mingw/otherlibs/systhreads/win32.c
+--- ocaml-3.11.0+beta1.orig/otherlibs/systhreads/win32.c       2007-10-31 09:12:29.000000000 +0000
++++ ocaml-3.11.0+beta1.mingw/otherlibs/systhreads/win32.c      2008-11-15 15:35:47.000000000 +0000
+@@ -13,6 +13,8 @@
+ /* $Id: win32.c,v 1.45 2007/10/31 09:12:29 xleroy Exp $ */
++#ifdef WIN32
++
+ /* Thread interface for Win32 threads */
+ #include <windows.h>
+@@ -662,3 +664,6 @@
+   sprintf(errmsg, "%s: error code %lx", msg, GetLastError());
+   raise_sys_error(copy_string(errmsg));
+ }
++
++#endif /* WIN32 */
++
diff --git a/ocaml/mingw32-ocaml-3.11.0+beta1-disable-cmxs.patch b/ocaml/mingw32-ocaml-3.11.0+beta1-disable-cmxs.patch
new file mode 100644 (file)
index 0000000..503ea53
--- /dev/null
@@ -0,0 +1,27 @@
+I couldn't get *.cmxs files to build in the cross-compiler.  This
+patch disables them.
+
+diff --exclude _build -urN ocaml-3.11.0+beta1.orig/otherlibs/Makefile.shared ocaml-3.11.0+beta1.mingw/otherlibs/Makefile.shared
+--- ocaml-3.11.0+beta1.orig/otherlibs/Makefile.shared  2008-07-15 16:31:32.000000000 +0100
++++ ocaml-3.11.0+beta1.mingw/otherlibs/Makefile.shared 2008-11-15 15:31:48.000000000 +0000
+@@ -42,7 +42,8 @@
+ all: lib$(CLIBNAME).$(A) $(LIBNAME).cma $(CMIFILES)
+-allopt: lib$(CLIBNAME).$(A) $(LIBNAME).cmxa $(LIBNAME).$(CMXS) $(CMIFILES)
++allopt: lib$(CLIBNAME).$(A) $(LIBNAME).cmxa $(CMIFILES)
++# $(LIBNAME).$(CMXS)
+ $(LIBNAME).cma: $(CAMLOBJS)
+       $(MKLIB) -o $(LIBNAME) -oc $(CLIBNAME) -ocamlc '$(CAMLC)' -linkall $(CAMLOBJS) $(LINKOPTS)
+@@ -50,8 +51,8 @@
+ $(LIBNAME).cmxa: $(CAMLOBJS_NAT)
+       $(MKLIB) -o $(LIBNAME) -oc $(CLIBNAME) -ocamlopt '$(CAMLOPT)' -linkall $(CAMLOBJS_NAT) $(LINKOPTS)
+-$(LIBNAME).cmxs: $(LIBNAME).cmxa lib$(CLIBNAME).$(A)
+-      $(CAMLOPT) -shared -o $(LIBNAME).cmxs -I . $(LIBNAME).cmxa
++#$(LIBNAME).cmxs: $(LIBNAME).cmxa lib$(CLIBNAME).$(A)
++#     $(CAMLOPT) -shared -o $(LIBNAME).cmxs -I . $(LIBNAME).cmxa
+ lib$(CLIBNAME).$(A): $(COBJS)
+       $(MKLIB) -oc $(CLIBNAME) $(COBJS) $(LDOPTS)
diff --git a/ocaml/mingw32-ocaml-3.11.0+beta1-filename-win32-dirsep.patch b/ocaml/mingw32-ocaml-3.11.0+beta1-filename-win32-dirsep.patch
new file mode 100644 (file)
index 0000000..bec95c5
--- /dev/null
@@ -0,0 +1,17 @@
+Our compiler will think that os_type = "Win32".  Unfortunately in
+the default OCaml this has the negative effect of causing it to
+use '\' character in paths.  Since it's really running on a Linux
+kernel, that won't work.  This is a quick and dirty fix.
+
+diff --exclude _build -urN ocaml-3.11.0+beta1.orig/stdlib/filename.ml ocaml-3.11.0+beta1.mingw/stdlib/filename.ml
+--- ocaml-3.11.0+beta1.orig/stdlib/filename.ml 2007-01-09 13:42:17.000000000 +0000
++++ ocaml-3.11.0+beta1.mingw/stdlib/filename.ml        2008-11-15 14:34:37.000000000 +0000
+@@ -68,7 +68,7 @@
+ module Win32 = struct
+   let current_dir_name = "."
+   let parent_dir_name = ".."
+-  let dir_sep = "\\"
++  let dir_sep = "/"
+   let is_dir_sep s i = let c = s.[i] in c = '/' || c = '\\' || c = ':'
+   let rindex_dir_sep s =
+     let rec pos i =
diff --git a/ocaml/mingw32-ocaml-3.11.0+beta1-i386-profiling.patch b/ocaml/mingw32-ocaml-3.11.0+beta1-i386-profiling.patch
new file mode 100644 (file)
index 0000000..b889676
--- /dev/null
@@ -0,0 +1,16 @@
+Make sure that PROFILE_* macros are defined on MinGW.  Not sure
+what to put in them yet, so at the moment they are just empty.
+
+diff -urN ocaml-3.11.0+beta1.orig/asmrun/i386.S ocaml-3.11.0+beta1.mingw/asmrun/i386.S
+--- ocaml-3.11.0+beta1.orig/asmrun/i386.S      2008-08-01 09:04:57.000000000 +0100
++++ ocaml-3.11.0+beta1.mingw/asmrun/i386.S     2008-11-15 15:08:20.000000000 +0000
+@@ -64,6 +64,9 @@
+         popl %edx; popl %ecx; popl %eax; popl %ebp
+ #define PROFILE_C \
+         pushl %ebp; movl %esp, %ebp; call Lmcount$stub; popl %ebp
++#elif defined(SYS_mingw)
++#define PROFILE_CAML
++#define PROFILE_C
+ #endif
+ #else
+ #define PROFILE_CAML
diff --git a/ocaml/mingw32-ocaml-3.11.0+beta1-no-stdlib-dir.patch b/ocaml/mingw32-ocaml-3.11.0+beta1-no-stdlib-dir.patch
new file mode 100644 (file)
index 0000000..b217e38
--- /dev/null
@@ -0,0 +1,21 @@
+Not sure if this is right, but OCAML_STDLIB_DIR can be undefined
+in our cross-compiler.  It's only used in a one place in the C
+code so this works around it.
+
+diff --exclude _build -urN ocaml-3.11.0+beta1.orig/byterun/dynlink.c ocaml-3.11.0+beta1.mingw/byterun/dynlink.c
+--- ocaml-3.11.0+beta1.orig/byterun/dynlink.c  2008-04-22 13:24:10.000000000 +0100
++++ ocaml-3.11.0+beta1.mingw/byterun/dynlink.c 2008-11-15 15:43:52.000000000 +0000
+@@ -80,7 +80,12 @@
+   stdlib = getenv("OCAMLLIB");
+   if (stdlib == NULL) stdlib = getenv("CAMLLIB");
+-  if (stdlib == NULL) stdlib = OCAML_STDLIB_DIR;
++  if (stdlib == NULL)
++#ifdef OCAML_STDLIB_DIR
++    stdlib = OCAML_STDLIB_DIR;
++#else
++    stdlib = ".";
++#endif
+   ldconfname = caml_stat_alloc(strlen(stdlib) + 2 + sizeof(LD_CONF_NAME));
+   strcpy(ldconfname, stdlib);
+   strcat(ldconfname, "/" LD_CONF_NAME);
diff --git a/ocaml/mingw32-ocaml-3.11.0+beta1-win32-fixes.patch b/ocaml/mingw32-ocaml-3.11.0+beta1-win32-fixes.patch
new file mode 100644 (file)
index 0000000..1e19167
--- /dev/null
@@ -0,0 +1,58 @@
+Misc fixes for byterun/win32.c
+
+diff --exclude _build -urN ocaml-3.11.0+beta1.orig/byterun/win32.c ocaml-3.11.0+beta1.mingw/byterun/win32.c
+--- ocaml-3.11.0+beta1.orig/byterun/win32.c    2008-04-22 13:24:10.000000000 +0100
++++ ocaml-3.11.0+beta1.mingw/byterun/win32.c   2008-11-15 15:50:32.000000000 +0000
+@@ -13,7 +13,6 @@
+ #include <windows.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+-#include <io.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+@@ -35,6 +36,26 @@
+ #include "flexdll.h"
++/* XXX including <io.h> gets ../byterun/io.h for some reason.
++ * Including the real io.h using the full path fails because of
++ * some strange bug in the system header file itself.  Give up and
++ * just define _finddata_t explicitly here.
++ */
++#ifndef _FSIZE_T_DEFINED
++typedef unsigned long   _fsize_t;
++#define _FSIZE_T_DEFINED
++
++struct _finddata_t
++{
++  unsigned        attrib;
++  time_t          time_create;
++  time_t          time_access;
++  time_t          time_write;
++  _fsize_t        size;
++  char            name[FILENAME_MAX];
++};
++#endif
++
+ #ifndef S_ISREG
+ #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
+ #endif
+@@ -93,7 +114,7 @@
+   pathlen = strlen(name) + 1;
+   if (pathlen < 256) pathlen = 256;
+   while (1) {
+-    fullname = stat_alloc(pathlen);
++    fullname = caml_stat_alloc(pathlen);
+     retcode = SearchPath(NULL,              /* use system search path */
+                        name,
+                        ".exe",            /* add .exe extension if needed */
+@@ -107,7 +128,7 @@
+       break;
+     }
+     if (retcode < pathlen) break;
+-    stat_free(fullname);
++    caml_stat_free(fullname);
+     pathlen = retcode + 1;
+   }
+   return fullname;
diff --git a/ocaml/mingw32-ocaml-3.11.0+beta1-win32unix-path.patch b/ocaml/mingw32-ocaml-3.11.0+beta1-win32unix-path.patch
new file mode 100644 (file)
index 0000000..064095d
--- /dev/null
@@ -0,0 +1,58 @@
+Combined Makefiles again: These libraries depend on the unix library,
+but really they depend on either the ("real") unix library or the
+win32unix library.  Include both, with win32unix first, on the basis
+that this should pick up the correct one in all cases.
+
+--- otherlibs/systhreads/Makefile.orig 2008-11-15 17:14:09.000000000 +0000
++++ otherlibs/systhreads/Makefile      2008-11-15 17:14:36.000000000 +0000
+@@ -15,8 +15,8 @@
+ include ../../config/Makefile
+-CAMLC=../../ocamlcomp.sh -I ../unix
+-CAMLOPT=../../ocamlcompopt.sh -I ../unix
++CAMLC=../../ocamlcomp.sh -I ../win32unix -I ../unix
++CAMLOPT=../../ocamlcompopt.sh -I ../win32unix -I ../unix
+ MKLIB=../../boot/ocamlrun ../../tools/ocamlmklib
+ COMPFLAGS=-warn-error A -g
+--- otherlibs/bigarray/Makefile.orig   2008-11-15 17:14:14.000000000 +0000
++++ otherlibs/bigarray/Makefile        2008-11-15 17:14:54.000000000 +0000
+@@ -14,8 +14,8 @@
+ # $Id: Makefile,v 1.25 2008/01/04 09:52:27 xleroy Exp $
+ LIBNAME=bigarray
+-EXTRACFLAGS=-I../unix -DIN_OCAML_BIGARRAY -DCAML_NAME_SPACE
+-EXTRACAMLFLAGS=-I ../unix
++EXTRACFLAGS=-I../win32unix -I../unix -DIN_OCAML_BIGARRAY -DCAML_NAME_SPACE
++EXTRACAMLFLAGS=-I ../win32unix -I ../unix
+ COBJS=bigarray_stubs.$(O) mmap_unix.$(O)
+ CAMLOBJS=bigarray.cmo
+ HEADERS=bigarray.h
+--- myocamlbuild.ml.orig       2008-11-15 17:25:50.000000000 +0000
++++ myocamlbuild.ml    2008-11-15 17:33:13.000000000 +0000
+@@ -116,9 +116,11 @@
+   if partial then ".."/dir else dir;;
+ let unix_dir =
+-  match Sys.os_type with
+-  | "Win32" -> if_partial_dir "otherlibs/win32unix"
+-  | _       -> if_partial_dir "otherlibs/unix";;
++  if_partial_dir (
++    let win32path = "otherlibs/win32unix" in
++    if Sys.file_exists (win32path / "unix.cma") then win32path
++    else "otherlibs/unix"
++  );;
+ let threads_dir    = if_partial_dir "otherlibs/threads";;
+ let systhreads_dir = if_partial_dir "otherlibs/systhreads";;
+--- ocamldoc/Makefile.orig     2008-11-15 17:49:57.000000000 +0000
++++ ocamldoc/Makefile  2008-11-15 17:50:25.000000000 +0000
+@@ -62,6 +62,7 @@
+ INCLUDES_NODEP=       -I $(OCAMLSRCDIR)/stdlib \
+       -I $(OCAMLSRCDIR)/otherlibs/str \
+       -I $(OCAMLSRCDIR)/otherlibs/dynlink \
++      -I $(OCAMLSRCDIR)/otherlibs/win32unix \
+       -I $(OCAMLSRCDIR)/otherlibs/unix \
+       -I $(OCAMLSRCDIR)/otherlibs/num \
+       -I $(OCAMLSRCDIR)/otherlibs/graph
index 08c18bb..f836786 100644 (file)
@@ -11,15 +11,33 @@ Summary:        Objective Caml MinGW cross-compiler and programming environment
 
 License:        QPL and (LGPLv2+ with exceptions)
 Group:          Development/Libraries
+
 URL:            http://caml.inria.fr/
 Source0:        http://caml.inria.fr/pub/distrib/ocaml-3.11/ocaml-%{version}.tar.bz2
-BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
+# This is installed as config/Makefile when we cross-compile.
+Source1000:     Makefile-fedora-mingw.in
+
+# XXX We should apply any Fedora native patches here.
+
+# For patch description, see the top of each patch file.
+# Start numbering at 1000 since these are MinGW-specific patches.
+Patch1000:      mingw32-ocaml-3.11.0+beta1-combined-Makefile.patch
+Patch1001:      mingw32-ocaml-3.11.0+beta1-disable-cmxs.patch
+Patch1002:      mingw32-ocaml-3.11.0+beta1-filename-win32-dirsep.patch
+Patch1003:      mingw32-ocaml-3.11.0+beta1-i386-profiling.patch
+Patch1004:      mingw32-ocaml-3.11.0+beta1-no-stdlib-dir.patch
+Patch1005:      mingw32-ocaml-3.11.0+beta1-win32-fixes.patch
+Patch1006:      mingw32-ocaml-3.11.0+beta1-win32unix-path.patch
+
+BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+# Is it noarch? (XXX)
 BuildArch:      noarch
 
 BuildRequires:  mingw32-filesystem >= 30
 BuildRequires:  mingw32-gcc
 BuildRequires:  mingw32-binutils
+BuildRequires:  mingw32-flexdll
 
 
 %description
@@ -33,42 +51,93 @@ and produces Windows native executables.
 %prep
 %setup -q -n ocaml-%{version}
 
+%patch1000 -p1
+%patch1001 -p1
+%patch1002 -p1
+%patch1003 -p1
+%patch1004 -p1
+%patch1005 -p1
+%patch1006 -p0
 
-%build
-# Remember that we're _not_ cross-compiling OCaml itself, we're trying
-# to build a Fedora native OCaml compiler (ocamlopt) which just has
-# the back-end part modified to generate Windows binaries.  So we
-# build as normal on a Unix system, but we make sure that ocamlopt
-# will use the Windows codegen and the MinGW assembler and linker.
 
-CFLAGS="$RPM_OPT_FLAGS" \
+%build
+# Build native ocamlrun and ocamlc which contain the filename-win32-dirsep
+# patch.
 ./configure \
+  -no-tk \
   -bindir %{_bindir} \
   -libdir %{_libdir}/ocaml \
-  -x11lib %{_libdir} \
-  -x11include %{_includedir} \
-  -mandir %{_mandir}/man1 \
-  -cc %{_mingw32_cc} \
-  -as %{_mingw32_as}
-
-# ./configure creates the following files:
-#     config/Makefile - containing mainly paths and names of build tools
-#     config/m.h - containing the machine description
-#     config/s.h - containing the environment / API description
-
-# Overwrite the generated m.h & s.h with the ones from Windows NT.
-cp config/m-nt.h config/m.h
-cp config/s-nt.h config/s.h
-
-make world bootstrap opt opt.opt
+  -mandir %{_mandir}/man1
+make world
+
+# Now move the working ocamlrun, ocamlc into the boot/ directory,
+# overwriting the binary versions which ship with the compiler with
+# ones that contain the above filename-win32-dirsep patch.
+make coreboot
+
+# Now replace the compiler configuration (config/{s.h,m.h,Makefile})
+# with ones as they would be on a 32 bit Windows system.
+pushd config
+
+# config/m.h can just be copied from config/m-nt.h which ships.
+rm -f m.h
+cp m-nt.h m.h
+
+# config/s.h can just be copied from config/s-nt.h which ships.
+rm -f s.h
+cp s-nt.h s.h
+
+# config/Makefile is a custom one which we supply.
+rm -f Makefile
+sed \
+  -e 's,@prefix@,%{_prefix},g' \
+  -e 's,@bindir@,%{_bindir},g' \
+  -e 's,@libdir@,%{_libdir},g' \
+  < %{SOURCE1000} > Makefile
+
+popd
+
+# We're going to build in otherlibs/win32unix and otherlibs/win32graph
+# directories, but since they would normally only be built under
+# Windows, they only have the Makefile.nt files.  Just symlink
+# Makefile -> Makefile.nt for these cases.
+for d in otherlibs/win32unix otherlibs/win32graph; do
+  ln -s Makefile.nt $d/Makefile
+done
+
+# Now clean the temporary files from the previous build.  This
+# will also cause asmcomp/arch.ml (etc) to be linked to the 32 bit
+# i386 versions, essentially causing ocamlopt to use the Win/i386 code
+# generator.
+make partialclean
+
+# Just rebuild some small bits that we need for the following
+# 'make opt' to work.  Note that 'make all' fails here.
+make -C byterun libcamlrun.a
+make ocaml ocamlc
+make -C stdlib
+make -C tools ocamlmklib
+
+# Build ocamlopt
+make opt
 
 
 %install
 rm -rf $RPM_BUILD_ROOT
-make DESTDIR=$RPM_BUILD_ROOT install
 
-# Remove static libraries but DON'T remove *.dll.a files.
-rm $RPM_BUILD_ROOT%{_mingw32_libdir}/libfoo.a
+# Only want to install ocamlopt and libraries.
+mkdir -p $RPM_BUILD_ROOT%{_bindir}
+mkdir -p $RPM_BUILD_ROOT%{_libdir}/i686-pc-mingw32-ocaml
+mkdir -p $RPM_BUILD_ROOT%{_libdir}/i686-pc-mingw32-ocaml/threads
+
+make installopt \
+  BINDIR=$RPM_BUILD_ROOT%{_bindir} \
+  LIBDIR=$RPM_BUILD_ROOT%{_libdir}/i686-pc-mingw32-ocaml
+
+# ocamlopt is a cross-compiler, so rename the binary.
+# XXX This should probably use %{_mingw32_target} macro.
+mv $RPM_BUILD_ROOT%{_bindir}/ocamlopt \
+  $RPM_BUILD_ROOT%{_bindir}/i686-pc-mingw32-ocamlopt
 
 
 %clean
@@ -77,11 +146,10 @@ rm -rf $RPM_BUILD_ROOT
 
 %files
 %defattr(-,root,root)
-%{_mingw32_bindir}/foo.dll
-%{_mingw32_libdir}/foo.dll.a
-# etc.
+%{_bindir}/i686-pc-mingw32-ocamlopt
+%{_libdir}/i686-pc-mingw32-ocaml/
 
 
 %changelog
-* Fri Nov 14 2008 Richard W.M. Jones <rjones@redhat.com> - 3.11.0+beta1-1
+* Sat Nov 15 2008 Richard W.M. Jones <rjones@redhat.com> - 3.11.0+beta1-1
 - Initial RPM release.