[MLton] Cygwin->Mingw32: patch + future

Wesley W. Terpstra terpstra@gkec.tu-darmstadt.de
Tue, 23 Nov 2004 02:36:28 +0100


--1yeeQ81UyVL57Vl7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Mon, Nov 22, 2004 at 03:37:06PM -0800, Stephen Weeks wrote:
> This looks like a good idea, if we can work around a problem or two.
> It does let us specify cc-opt, and link-opt, as well as other options
> on a per-target basis with more flexibility than the current approach.
> 
> One problem that I see is where do we put the -target-{cc,link}-opt
> options that currently live in mlton-script before the
> lib/mlton/<target> directories are created?

What's wrong with creating a big collection of directories with only default
options? It's not like disk space is an issue. Besides, it's advertising. ;)

The libs and entries in target-map would not be present so the directories
would not be used. With so many subdirs a lib/mlton/target/* dir might be a
good idea to keep things organized. I am not suggesting we include every
possible target; only those which we know good options for.

BTW. I've attached another patch for cross-compiling.
This time from linux->mingw (was testing it).

When picking the temp dir to use during build, you should use the 
compiler's host to pick the dir---not the target. (cross-compile-bug.patch)

> With your approach, I guess we don't need -target-cc, since instead we
> would have an appropriate -cc flag in lib/mlton/<target>/flags.  And
> maybe we don't even need multiple words, since we can make the first
> -cc-opt be the appropriate -b or -mno-cygwin.  And MLton will preserve
> the order of the cc options.

You're right; that's better.

> > I propose to remove all the text/binary toggles out of the
> > SML library and put all MLton filedescs in binary mode. Then add translation
> > at the level of TextIO. More work to be done in the MLton basis library,
> > true. However, this will probably be more portable in the long run and
> > makes several otherwise impossible problems solvable
> ...
> > Make both TextIO.stdin and BinIO.stdin point to the same underlying buffer
> > and bingo, it finally works the way C should have. If you combine this with
> > your above suggestion of returning the same stream, one can even guarantee
> > that reads/writes to the same fd are not order-mangled by the buffers.
> 
> This seems like a fine idea to me.  I am interested to hear others'
> thoughts though.

I'd like to keep this issue seperate from the pipe issue I'm working on now
if you don't mind. I'll look into this after the MLton.Child is perfected.
Probably also after the cross-compile options control too; that keeps
causing trouble---on debian my cross-compiler is i586-mingw32msvc-gcc and
there is no 'gcc -b <asda>' option that will run it.

I know they're related, but I would prefer to keep the patches separate.
(This means that setbin/text will be added only to be removed later)

The stdin translation issue is not critical for the application I am trying
to finish and publication deadlines are looming.

PS. The reason I am using SML and not OCaml: the OCaml guys swallowed my
kill() patch for mingw into the void of ignored email... and Word32.

> > > 	    val lie: 'a isNotPipe t -> 'a isPipe t
> > 
> > Uhm, "lie"?
> > That sounds like a dangerous option.
> > What's it for?
> 
> The idea was that one might want to write a piece of code (e.g. a
> shell) that dynamically decides whether or not an argument to create
> is a pipe.

A worthy use-case.
I need to digest this a bit.

> > To keep cygwin on the level of mingw, I've switched cygwin to using
> > fork() and mmap(). For me, it appears to work (I have the newest
> > cygwin). The change to enable cygwin+fork() is currently part of my
> > patchset.
> 
> Unfortunately, using fork+mmap is still not acceptable on Cygwin in
> some cases.  See http://mlton.org/RunningOnCygwin

I've already read that.

What's the problem? You shouldn't be requiring contiguous address space
anyways; that's never going to be possible to achieve portably. Also, I've
rebuilt mlton several times now using the mlton with mmap instead of
VirtualAlloc. Are there really any bigger projects than MLton itself?

What sort of problems does this cause?
I see random segfaults of the mlton compiler under cygwin, but I had those
with the VirtualAlloc version too. I haven't spent time tracking it yet.

> > I intend to figure out how to run the regression tests today.
> > However, I only have access to cygwin, mingw32, and linux.
> 
> That's fine.  We test the other platforms sporadically, and I will try
> to remember run some tests after the checkin.

Those regression tests don't test Unix.* at all it seems.

I've tried it now on linux->linux, linux->mingw, cygwin->cygwin, and
cygwin->mingw. My test cases all appear to work.

In fact, I was going to send you my 'final' patch, but your interface
changes below mean I've got more to do tomorrow. Hopefully they can be
achieved with cosmetic data layout changes only.

I've attached it anyways (windows-pipes.patch.gz).

> It makes sense. I think it can be cleaned up a little.

I need to sleep on this.
I'll get back to you.

I did it your way first, but then changed it to this because I couldn't get
the implementation to fit. However, in the process of getting it work I've
become more familiar with how SML's type system works so I can try again.

PS. I _hate_ the polymorphic value rule. %^#$%@#

> Finally, for cases like toTextIOin, where you use TextIO.instream as a
> phantom type, I prefer to use a new phantom type, since that makes it
> clear that there is no connection between the TextIO.instream on the left
> and on the right of the arrow.

I have two objections:

1. No connection?
   It seems to me to be a great deal more specific to say 'this thing was
   used as a TextIO.instream so you can only get it out that way later'.
   What is 'text'? If you read between the lines it's TextIO.*stream.
   I think we should rather be upfront about what it is bound to.
   
   The error messages then also fit:
	  Function applied to incorrect argument.
	    expects: ([TextIO.instream], _) child
	    but got: ([BinIO.instream], _) child
	    in: toTextIOin (getStdout p)

2. More parts bad
   More types = more confusion to the user who tries to read and understand
   what the type signature means.

As a scary thought before I go to sleep, I wonder if this is a good idea at
all? Just because Unix.* did it certainly doesn't mean it's right. It might
make sense to want to open a pipe as WideTextIO, BinIO, and TextIO all at
once and read things from one then the other. If the buffering is shared
like we discussed earlier, this is well-defined.

One last thing: the MLton mailing lists use a very bad web email archiver.
There's no way to download attachments or search it! At the risk of sounding
biased, may I suggest lurker.sf.net? <http://people.debian.org/~terpstra>

Good night.

-- 
Wesley W. Terpstra

--1yeeQ81UyVL57Vl7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="cross-compile-bug.patch"

--- main.fun.orig	2004-11-23 00:45:13.000000000 +0100
+++ main.fun	2004-11-23 00:47:23.000000000 +0100
@@ -735,7 +735,7 @@
 		     val tmpDir =
 			let
 			   val (tmpVar, default) =
-			      case targetOS of
+			      case MLton.Platform.OS.host of
 				 MinGW => ("TEMP", "C:/WINNT/TEMP")
 			       | _ => ("TMPDIR", "/tmp")
 			in

--1yeeQ81UyVL57Vl7
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="windows-pipes.patch.gz"
Content-Transfer-Encoding: base64

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

--1yeeQ81UyVL57Vl7--