[MLton-user] Which MinGW version is recommended?

Stephen Weeks MLton-user@mlton.org
Thu, 7 Aug 2003 14:54:28 -0700


Brent:
> I have been trying to use the Cygwin build of MLton to build a working
> MLton but get errors using GCC 3.2.3 (from the Cygwin site.)  I built
> GCC 3.3, but this also fails due to some breakage in the system call
> to gcc:
> 
> $ make constants
> Creating constants file.
> ./build/bin/mlton -build-constants true >tmp.c
> ./build/bin/mlton -output tmp tmp.c
> call to system failed: gcc -c -I./build/bin/../lib/self/include -O1
> -fno-strict-aliasing -fomit-frame-pointer -w -fno-strength-reduce
> -fschedule-insns -fschedule-insns2 -malign-functions=5
> -malign-jumps=2 -malign-loops=2 -mcpu=pentiumpro -o /tmp/fileJu9OfK.o tmp.c
> make: *** [constants] Error 1

The short explanation is that on Cygwin, Posix.Process.fork is
unimplemented and raises SysErr with Posix.Error.nosys.  Now for the
long explanation.

MLton calls gcc via System.system (see mlton/control/system.sml).
This calls MLton.Process.spawnp, which in turn calls the C spawnvp
function (see basis-library/mlton/process.sml and
runtime/basis/MLton/spawnp.c).  The spawn stuff was necessary because
of bugs in Cygwin's implementation of fork, which is why MLton
disables fork on Cygwin.  Anyways, the use of spawn is portable across
all the platforms MLton runs on.

However, there are stubs (see lib/mlton-stubs/*) that emulate enough
of the MLton structure of MLton's library so that MLton can be
compiled by another version of itself without using the MLton
structure from the other version.  These stubs define
MLton.Process.spawnp in terms of fork/execp (see
lib/mlton-stubs/mlton.sml).  These stubs only get used when compiling
MLton with another version of itself (see mlton/Makefile).

The upshot is that you will see this problem when bootstrapping from
clean sources on a Cygwin machine, because the first-round compiler
will be built with the stubs.  The easiest way I can think of to work
around this is to edit mlton/Makefile to avoid using the stubs.
Adding the following line after the other CM lines should do it.

  CM = $(NAME).cm

This should work fine when you're compiling the sources that come with
the MLton binary package, since the MLton structure is the same in
both versions, making the stubs unnecessary.

I'll think about a fix that doesn't require people to patch the
Makefile.

BTW, you may encounter another problem on Cygwin due to "time"
segfaulting.  This easiest fix for this is to remove the calls to time
from the Makefiles.

Brent:
> Is there any way to capture the error code the system call is
> generating ...

I've added a patch to mlton/control/system.sml that includes the
exception that was raised in the error message.

diff -u -r1.3 system.sml
--- mlton/control/system.sml	16 Apr 2002 12:10:52 -0000	1.3
+++ mlton/control/system.sml	7 Aug 2003 20:36:28 -0000
@@ -62,7 +62,7 @@
 	       end
 	 in
 	    Process.wait (MLton.Process.spawnp {file = com, args = com :: args})
-	    handle _ => Error.bug (concat ["call to system failed: ", s])
-	       (* OS.Process.success = OS.Process.system s *)
+	    handle e => Error.bug (concat ["call to system failed with ",
+					   Exn.toString e, ":\n", s])
 	 end
    end

You can apply this patch and build from clean sources to get a better
error message.  But there should be no need if the above explanation
is correct.

> That makes me scared that a more sinister bug is preventing
> system-level calls from working. 

That is correct, but only system-level calls made by a first-round
compiler (ergo rendering the first-round compiler useless).  Not that
I am saying that this is a good thing :-).  I just want to be clear
that there is no problem with the distributed MLton binary (which was
generated by a cross compile) or with MLton-generated Cygwin
executables.  The only problem is with the stubs that get included in
the first-round compile.

Jesper:
> I've seen exactly the same bug on the NetBSD port I am currently working
> on.

I'm not sure why you would see this on NetBSD, unless fork is failing
there.  I'll try to set up a NetBSD system and see if I can help out.

Anoq:
> The constants file is a very critical point in cross-compilation (if
> that's what you are doing?). Basically you want the correct compiler
> to compile for the correct platform and then to execute that file on
> the correct platform. I think there are actually 2 steps where the
> constantsfiles are generated (IIRC?). At one of the steps the
> constants file must be cross-compiled to the target platform with
> the cross-compiler and executed on the _target_ platform (unless
> they made some workarounds for this with clever include files from
> the target-platforms?).

The constants file is generated only once -- bin/add-cross builds and
compiles it on the host and then runs it on the cross host.  We
decided on that as the most reliable way of getting the right
constants.  We don't use any include file tricks.

Hopefully this enough to let the ports continue.  Please send mail
with any other problems.