OCaml "4.07.0+default-unsafe-string+mingw32" working for Windows XP SP3

The project that uses OCaml wants to use Unicode support added in 4.07. The compilation process is happening on Windows XP so the output binary can be run on XP\Vista\8\10 and 11.

Is there any way to get OCaml “4.07.0+default-unsafe-string+mingw32” working for Windows XP SP3?

I have Cygwin for windows xp working with all dependencies, but opam doesn’t run (dll error), OCaml copied from win7 doesn’t run either (The procedure entry point _putenv_s could not be located in the dynamic link library msvcrt.dll.)

Does anyone has a ‘working XP setup’?

This looks like a question for @dra27.

Cheers,
Nicolas

Recent version’s of gcc, mingw-w64 and OCaml have all dropped Windows XP support long time ago. If you use recent versions of them to compile your program, it won’t run on Windows XP.

You can try to use a more recent version of Windows as your build os (vista should be ok).

  1. Install an old version of cygwin and the mingw toolchain ( mingw64-i686-gcc-core, mingw64-i686-runtime, mingw64-i686-headers ) from: Cygwin Time Machine

  2. Install opam manually inside cygwin.

  3. bootstrap an old OCaml version, e.g. opam switch create 4.07.0+default-unsafe-string+mingw32

  4. compile your program

  5. test, if the generated binary works under XP.

Caveats:

  1. OCaml stopped supporting Windows XP silently. It’s not documented inside Changes that the corresponding PR uses features that are only available on Vista or later.

  2. Older compiler descriptions from opam-repository-mingw are patched, otherwise they would not longer work with recent versions of gcc/mingw-w64. I’ve never checked, if the changes are compatible with ancient versions of gcc/mingw-w64.

Obviously (:rofl:) I do have a working Windows XP SP3 VM, but you really, really, really shouldn’t be doing this! (see @fdopen’s reply!)

You need this patch to 4.07 (PR 1406 was the Windows XP breaker):

diff --git a/runtime/win32.c b/runtime/win32.c
index d72c954..24c806a 100644
--- a/runtime/win32.c
+++ b/runtime/win32.c
@@ -17,11 +17,6 @@

 /* Win32-specific stuff */

-/* FILE_INFO_BY_HANDLE_CLASS and FILE_NAME_INFO are only available from Windows
-   Vista onwards */
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600
-
 #define WIN32_LEAN_AND_MEAN
 #include <wtypes.h>
 #include <winbase.h>
@@ -947,6 +942,14 @@ void caml_restore_win32_terminal(void)
 /* Detect if a named pipe corresponds to a Cygwin/MSYS pty: see
    https://github.com/mirror/newlib-cygwin/blob/00e9bf2/winsup/cygwin/dtable.cc#L932
 */
+typedef struct _FILE_NAME_INFO {
+         DWORD FileNameLength;
+           WCHAR FileName[1];
+} FILE_NAME_INFO, *PFILE_NAME_INFO;
+typedef enum _FILE_INFO_BY_HANDLE_CLASS {
+  FileBasicInfo /* is zero? */,
+  FileStandardInfo,
+    FileNameInfo} FILE_INFO_BY_HANDLE_CLASS, *PFILE_INFO_BY_HANDLE_CLASS;
 typedef
 BOOL (WINAPI *tGetFileInformationByHandleEx)(HANDLE, FILE_INFO_BY_HANDLE_CLASS,
                                              LPVOID, DWORD);

and you will need to bootstrap flexdll with this patch:

diff --git a/flexdll.c b/flexdll.c
index b19fe2a..e7aa4a2 100644
--- a/flexdll.c
+++ b/flexdll.c
@@ -381,7 +381,7 @@ void *flexdll_wdlopen(const wchar_t *file, int mode) {
   sprintf(flexdll_relocate_env,"%p",relocate);
   setenv("FLEXDLL_RELOCATE", flexdll_relocate_env, 1);
 #else
-#if __STDC_SECURE_LIB__ >= 200411L
+#if 0 /*__STDC_SECURE_LIB__ >= 200411L && !defined(__MINGW32__)*/
   sprintf(flexdll_relocate_env,"%p",relocate);
   _putenv_s("FLEXDLL_RELOCATE", flexdll_relocate_env);
 #else
2 Likes

I’m aware of the drawbacks but I’m afraid that dropping support for Windows XP is not an option for the project. And It’s not my decision to make. I will share your concerns with the project mantainer.

@fdopen Using old Cygwin version, after many attempts, I was not able to install opam on vista. The opam init fails without downloading any kind of repository. I will try one more time using Windows 7 but from what I know, the produced binary doesn’t work on Windows XP.

@dra27

Many thanks for these detailed instructions. Even I’m tech-savvy, I think those will still be a challenge for me. So first let me clarify some things:

  1. By saying ‘I have up and running XP SP3 VM’ are you saying that you have Cygwin setup that allows for the compilation of 4.07.0+default-unsafe-string+mingw32 there?

  2. Does apply those patches mean that I would also need to use Windows XP for compilation? Or those patches are to fix ‘produced binaries’ so the compilation on Windows 7/10/11 will produce a working executable for Windows XP?

  3. What exactly bootstrap flexdll means? I saw this step when I try to compile OCaml, does apply the patch to the ocaml source will be enough?

Yes, my Windows XP VM compiles OCaml (that’s of course not strictly the same thing as installing opam and building that specific package). However, the patch to win32.c should be enough to allow you to build a binary on Windows 10 and run it on Windows XP (but I haven’t tested that).

Bootstrapping flexdll means dumping the flexdll sources in flexdll/, patching them, and then running make flexdll before running make world.opt. The flexdll patches are necessary to answer your original question to get OCaml 4.07 working on Windows XP - that’s not necessary if you patch OCaml 4.07 from Windows 10 and copy the binaries back.

2 Likes

@dra27 I can successfully apply the patch but I face the following problem:

  1. When I’m using opam switch create 4.07.0+default-unsafe-string+mingw32 I can find win32.c file at .opam\4.07.0+default-unsafe-string+mingw32\.opam-switch\sources\ocaml-variants.4.07.0+default-unsafe-string+mingw32\byterun and I can successfully apply the patch.
  2. But the ocaml is already compiled so ocaml bin doesn’t have it.
  3. Before using opam switch create I cannot find win32.c file anywhere inside .opam dir.

What I’m missing?

Hey, any updates?

@fdopen Maybe you can help me understand the correct workflow to get the patched OCaml?