[MLton] A few changes proposals for MLton
Matthew Fluet
fluet at tti-c.org
Fri Nov 14 16:02:34 PST 2008
On Thu, 13 Nov 2008, Nicolas Bertolotti wrote:
> * 01-cross-compile-mlton.patch
> * This patch modifies the MLton Makefiles in order to make it
> easier to build a MLton cross compiler by cross compiling the
> runtime and only use the target machine to run the needed binaries
> (gen-sizes, print-constants etc...). It introduces a Makefile
> parameter TARGET_MACHINE that can be used in order to provide the
> hostname of the machine that should be used to run those binaries.
> The machine is then accessed through "ssh".
I don't have any experience with using cross compilers, so if it works for
you and doesn't impact things when non cross compiling, then it is
probably fine.
Two notes:
diff -Naur mlton-r6658.orig/runtime/Makefile mlton-r6658/runtime/Makefile
--- mlton-r6658.orig/runtime/Makefile 2008-06-16 16:03:08.000000000 +0200
+++ mlton-r6658/runtime/Makefile 2008-06-16 16:42:12.000000000 +0200
@@ -285,7 +296,7 @@
gen/basis-ffi.h gen/basis-ffi.sml: gen/gen-basis-ffi.sml gen/basis-ffi.def
mlton -output gen/gen-basis-ffi gen/gen-basis-ffi.sml
rm -f gen/basis-ffi.h gen/basis-ffi.sml
- cd gen && ./gen-basis-ffi
+ cd gen && $(TARGET_EXEC_BEGIN) ./gen-basis-ffi $(TARGET_EXEC_FILE)
rm -f gen/gen-basis-ffi
basis-ffi.h: gen/basis-ffi.h
This is (a) broken and (b) unecessary. This will have compiled
gen-basis-ffi.sml using the host mlton with no -target option, so the
resulting gen-basis-ffi executable will be for the host, but it is being
executed on the target machine. Also, gen-basis-ffi reads directly from
basis-ffi.def and writes directly to basis-ffi.h and basis-ffi.sml, which
aren't being copied to/from the target machine. You probably never
encountered this because the derived basis-ffi.{h,sml} files are in the
repository. In any case, the gen-basis-ffi program simply textually
processes basis-ffi.def, with no target dependencies. Hence, there is no
need to execute it on the target machine.
diff -Naur mlton-r6658.orig/bin/upgrade-basis mlton-r6658/bin/upgrade-basis
--- mlton-r6658.orig/bin/upgrade-basis 2008-06-16 16:08:02.000000000 +0200
+++ mlton-r6658/bin/upgrade-basis 2008-06-16 16:40:47.000000000 +0200
@@ -11,14 +11,15 @@
name=`basename "$0"`
usage () {
- die "usage: $name <PATH> <ARCH> <OS>"
+ die "usage: $name <PATH> <ARCH> <OS> <TARGET>"
}
case "$#" in
-3)
+4)
PATH="$1"
ARCH="$2"
OS="$3"
+ TARGET="$4"
;;
*)
usage
@@ -28,7 +29,7 @@
tmp="$$.sml"
echo "val () = print \"I work\"" >"$tmp"
-if ! mlton "$tmp" 1>&2; then
+if ! mlton -target $TARGET "$tmp" 1>&2; then
die "Error: cannot upgrade basis because the compiler doesn't work"
fi
@@ -36,7 +37,7 @@
feature="$1"
sml="$2"
echo "$feature" >"$tmp"
- if ! mlton -stop tc "$tmp" >/dev/null 2>&1; then
+ if ! mlton -target $TARGET -stop tc "$tmp" >/dev/null 2>&1; then
echo "$sml"
fi
}
diff -Naur mlton-r6658.orig/mlton/Makefile mlton-r6658/mlton/Makefile
--- mlton-r6658.orig/mlton/Makefile 2008-06-16 16:04:17.000000000 +0200
+++ mlton-r6658/mlton/Makefile 2008-06-16 16:40:47.000000000 +0200
@@ -9,8 +9,8 @@
SRC := $(shell cd .. && pwd)
BUILD := $(SRC)/build
BIN := $(BUILD)/bin
-HOST_ARCH := $(shell "$(SRC)/bin/host-arch")
-HOST_OS := $(shell "$(SRC)/bin/host-os")
+TARGET_ARCH := $(shell "$(SRC)/bin/host-arch")
+TARGET_OS := $(shell "$(SRC)/bin/host-os")
LIB := $(BUILD)/lib
MLTON := mlton
TARGET := self
@@ -27,12 +27,12 @@
FLAGS += -default-ann 'warnUnused true'
# FLAGS += -type-check true -show-types true
else
-ifeq (cygwin, $(HOST_OS))
+ifeq (cygwin, $(TARGET_OS))
# The stubs don't work on Cygwin, since they define spawn in terms of
# fork, and fork doesn't work on Cygwin. So, make without the stubs.
FILE := mlton.cm
else
-ifeq (mingw, $(HOST_OS))
+ifeq (mingw, $(TARGET_OS))
# Ditto for MinGW.
FILE := mlton.cm
else
@@ -87,7 +87,7 @@
#! Pass $(PATH) to upgrade-basis because it is run via #!/usr/bin/env
# bash, which resets the path.
$(UP):
- "$(SRC)/bin/upgrade-basis" '$(PATH)' "$(HOST_ARCH)" "$(HOST_OS)" >$(UP)
+ "$(SRC)/bin/upgrade-basis" '$(PATH)' "$(TARGET_ARCH)" "$(TARGET_OS)" "$(TARGET)" >$(UP)
mlton.sml: $(SOURCES)
rm -f mlton.sml && mlton -stop sml mlton.cm && chmod -w mlton.sml
It isn't clear to me why upgrade-basis needs to know the target. In any
case, your changes don't seem to completely support cross compiling the
compiler. For example, in <src>/Makefile, in the 'world-no-check' target,
you don't execute the compiler on the target system, which would be
necessary after a
make TARGET=xx TARGET_ARCH=xx TARGET_OS=xx TARGET_MACHINE=xx compiler
to have both build/lib/mlton-compile and build/lib/world.mlton for the
target.
It seems to me that your changes support the following workflow:
# start from a clean slate
make clean
# bootstrap; resulting compiler only supports -target self
make
# cross compile the runtime
## first, get self objects/archives out of the way
make -C runtime clean
make TARGET=xx TARGET_ARCH=xx TARGET_OS=xx TARGET_MACHINE=xx runtime
# there are new target specific files in basis-library/config/c
## this is just a target agnostic copy operation
make basis-no-check
# get the new target constants
make TARGET=xx TARGET_ARCH=xx TARGET_OS=xx TARGET_MACHINE=xx constants
# register the new target
make TARGET=xx TARGET_ARCH=xx TARGET_OS=xx TARGET_MACHINE=xx targetmap
Now, "build/bin/mlton -target new" works, but is a self executable. It
wouldn't be wise to do
make TARGET=xx TARGET_ARCH=xx TARGET_OS=xx TARGET_MACHINE=xx compiler
because that would overwrite build/lib/mlton-compile with a target
executable.
So, despite the existence of the TARGET variable in the mlton/Makefile,
I'm not sure how easy/useful it is to produce a cross-compiled
mlton-compile from within the Makefile system. But, I could be wrong.
More information about the MLton
mailing list