Porting MLton to a new target platform (architecture or OS) involves the following steps.
-
Make the necessary changes to the scripts, runtime system, Basis Library implementation, and compiler.
-
Get the regressions working using a cross compiler.
-
Bootstrap MLton on the target.
MLton has a native code generator only for AMD64 and X86, so, if you are porting to another architecture, you must use the C code generator. These notes do not cover building a new native code generator.
Some of the following steps will not be necessary if MLton already supports the architecture or operating system being ported to.
What code to change
-
Scripts.
-
In
bin/platform
, add new cases to define$HOST_OS
and$HOST_ARCH
.
-
-
Runtime system.
The goal of this step is to be able to successfully run
make
in theruntime
directory on the target machine.-
In
platform.h
, add a new case to includeplatform/<arch>.h
andplatform/<os>.h
. -
In
platform/<arch>.h
:-
define
MLton_Platform_Arch_host
.
-
-
In
platform/<os>.h
:-
include platform-specific includes.
-
define
MLton_Platform_OS_host
. -
define all of the
HAS_*
macros.
-
-
In
platform/<os>.c
implement any platform-dependent functions that the runtime needs. -
Add rounding mode control to
basis/Real/IEEEReal.c
for the new arch (if notHAS_FEROUND
) -
Build and install the GMP development library. This varies from platform to platform.
-
-
Basis Library implementation (
basis-library/*
)-
In
primitive/prim-mlton.sml
:-
Add a new variant to the
MLton.Platform.Arch.t
datatype. -
modify the constants that define
MLton.Platform.Arch.host
to match withMLton_Platform_Arch_host
, as set inruntime/platform/<arch>.h
. -
Add a new variant to the
MLton.Platform.OS.t
datatype. -
modify the constants that define
MLton.Platform.OS.host
to match withMLton_Platform_OS_host
, as set inruntime/platform/<os>.h
.
-
-
In
mlton/platform.{sig,sml}
add a new variant. -
In
sml-nj/sml-nj.sml
, modifygetOSKind
. -
Look at all the uses of
MLton.Platform
in the Basis Library implementation and see if you need to do anything special. You might use the following command to see where to look.find basis-library -type f | xargs grep 'MLton\.Platform'
If in doubt, leave the code alone and wait to see what happens when you run the regression tests.
-
-
Compiler.
-
In
lib/stubs/mlton-stubs/platform.sig
add any new variants, as was done in the Basis Library. -
In
lib/stubs/mlton-stubs/mlton.sml
add any new variants inMLton.Platform
, as was done in the Basis Library.
-
The string used to identify a particular architecture or operating
system must be the same (except for possibly case of letters) in the
scripts, runtime, Basis Library implementation, and compiler (stubs).
In mlton/main/main.fun
, MLton itself uses the conversions to and
from strings:
MLton.Platform.{Arch,OS}.{from,to}String
If the there is a mismatch, you may see the error message
strange arch
or strange os
.
Running the regressions with a cross compiler
When porting to a new platform, it is always best to get all (or as
many as possible) of the regressions working before moving to a self
compile. It is easiest to do this by modifying and rebuilding the
compiler on a working machine and then running the regressions with a
cross compiler. It is not easy to build a gcc cross compiler, so we
recommend generating the C and assembly on a working machine (using
MLton’s -target
and -stop g
flags, copying the generated files to
the target machine, then compiling and linking there.
-
Remake the compiler on a working machine.
-
Use
bin/add-cross
to add support for the new target. In particular, this should createbuild/lib/mlton/targets/<target>/
with the platform-specific necessary cross-compilation information. -
Run the regression tests with the cross-compiler. To cross-compile all the tests, do
bin/regression -cross <target>
This will create all the executables. Then, copy
bin/regression
and theregression
directory to the target machine, and dobin/regression -run-only <target>
This should run all the tests.
Repeat this step, interleaved with appropriate compiler modifications, until all the regressions pass.
Bootstrap
The idea for bootstrapping MLton on a new platform is as follows:
-
send the current sources to a remote machine (using ssh)
-
build the MLton runtime system on the remote machine
-
receive the built runtime system from the remote machine as a new target on the host machine
-
build bootstrap compiler sources on the host machine for the new target
-
send the boostrap sources to the remote machine
-
build the boostrap compiler on the remote machine using the boostrap compiler sources
-
complete the MLton build on the remote machine with the boostrap compiler to obtain a boot package
-
build MLton on the remote machine from clean sources using the boot package
-
receive the built binary release from the remote machine
The remote-bootstrap
goal of the root Makefile
automates this process; see
comments in the root Makefile
. Here is an example bootstrapping on an OpenBSD
machine (named thunder
):
$ make REMOTE_MACHINE=thunder REMOTE_MAKE=gmake REMOTE_MAKEFLAGS=WITH_GMP_DIR=/usr/local remote-bootstrap
Once you’ve got a compiler on the target machine, you should test it by running all the regressions normally and by running a couple rounds of self compiles.