<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="AsciiDoc 9.0.0rc1">
<title>PortingMLton</title>
<link rel="stylesheet" href="./asciidoc.css" type="text/css">
<link rel="stylesheet" href="./pygments.css" type="text/css">


<script type="text/javascript" src="./asciidoc.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
asciidoc.install();
/*]]>*/
</script>
<link rel="stylesheet" href="./mlton.css" type="text/css">
</head>
<body class="article">
<div id="banner">
<div id="banner-home">
<a href="./Home">MLton 20210117</a>
</div>
</div>
<div id="header">
<h1>PortingMLton</h1>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>Porting MLton to a new target platform (architecture or OS) involves
the following steps.</p></div>
<div class="olist arabic"><ol class="arabic">
<li>
<p>
Make the necessary changes to the scripts, runtime system,
<a href="BasisLibrary"> Basis Library</a> implementation, and compiler.
</p>
</li>
<li>
<p>
Get the regressions working using a cross compiler.
</p>
</li>
<li>
<p>
Bootstrap MLton on the target.
</p>
</li>
</ol></div>
<div class="paragraph"><p>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.</p></div>
<div class="paragraph"><p>Some of the following steps will not be necessary if MLton already
supports the architecture or operating system being ported to.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_what_code_to_change">What code to change</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
Scripts.
</p>
<div class="openblock">
<div class="content">
<div class="ulist"><ul>
<li>
<p>
In <span class="monospaced">bin/platform</span>, add new cases to define <span class="monospaced">$HOST_OS</span> and <span class="monospaced">$HOST_ARCH</span>.
</p>
</li>
</ul></div>
</div></div>
</li>
<li>
<p>
Runtime system.
</p>
<div class="openblock">
<div class="content">
<div class="paragraph"><p>The goal of this step is to be able to successfully run <span class="monospaced">make</span> in the
<span class="monospaced">runtime</span> directory on the target machine.</p></div>
<div class="ulist"><ul>
<li>
<p>
In <span class="monospaced">platform.h</span>, add a new case to include <span class="monospaced">platform/&lt;arch&gt;.h</span> and <span class="monospaced">platform/&lt;os&gt;.h</span>.
</p>
</li>
<li>
<p>
In <span class="monospaced">platform/&lt;arch&gt;.h</span>:
</p>
<div class="ulist"><ul>
<li>
<p>
define <span class="monospaced">MLton_Platform_Arch_host</span>.
</p>
</li>
</ul></div>
</li>
<li>
<p>
In <span class="monospaced">platform/&lt;os&gt;.h</span>:
</p>
<div class="ulist"><ul>
<li>
<p>
include platform-specific includes.
</p>
</li>
<li>
<p>
define <span class="monospaced">MLton_Platform_OS_host</span>.
</p>
</li>
<li>
<p>
define all of the <span class="monospaced">HAS_*</span> macros.
</p>
</li>
</ul></div>
</li>
<li>
<p>
In <span class="monospaced">platform/&lt;os&gt;.c</span> implement any platform-dependent functions that the runtime needs.
</p>
</li>
<li>
<p>
Add rounding mode control to <span class="monospaced">basis/Real/IEEEReal.c</span> for the new arch (if not <span class="monospaced">HAS_FEROUND</span>)
</p>
</li>
<li>
<p>
Build and install the <a href="GMP">GMP</a> development library.  This varies from platform to platform.
</p>
</li>
</ul></div>
</div></div>
</li>
<li>
<p>
Basis Library implementation (<span class="monospaced">basis-library/*</span>)
</p>
<div class="openblock">
<div class="content">
<div class="ulist"><ul>
<li>
<p>
In <span class="monospaced">primitive/prim-mlton.sml</span>:
</p>
<div class="ulist"><ul>
<li>
<p>
Add a new variant to the <span class="monospaced">MLton.Platform.Arch.t</span> datatype.
</p>
</li>
<li>
<p>
modify the constants that define <span class="monospaced">MLton.Platform.Arch.host</span> to match with <span class="monospaced">MLton_Platform_Arch_host</span>, as set in <span class="monospaced">runtime/platform/&lt;arch&gt;.h</span>.
</p>
</li>
<li>
<p>
Add a new variant to the <span class="monospaced">MLton.Platform.OS.t</span> datatype.
</p>
</li>
<li>
<p>
modify the constants that define <span class="monospaced">MLton.Platform.OS.host</span> to match with <span class="monospaced">MLton_Platform_OS_host</span>, as set in <span class="monospaced">runtime/platform/&lt;os&gt;.h</span>.
</p>
</li>
</ul></div>
</li>
<li>
<p>
In <span class="monospaced">mlton/platform.{sig,sml}</span> add a new variant.
</p>
</li>
<li>
<p>
In <span class="monospaced">sml-nj/sml-nj.sml</span>, modify <span class="monospaced">getOSKind</span>.
</p>
</li>
<li>
<p>
Look at all the uses of <span class="monospaced">MLton.Platform</span> 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.
</p>
<div class="listingblock">
<div class="content monospaced">
<pre>find basis-library -type f | xargs grep 'MLton\.Platform'</pre>
</div></div>
<div class="paragraph"><p>If in doubt, leave the code alone and wait to see what happens when you run the regression tests.</p></div>
</li>
</ul></div>
</div></div>
</li>
<li>
<p>
Compiler.
</p>
<div class="openblock">
<div class="content">
<div class="ulist"><ul>
<li>
<p>
In <span class="monospaced">lib/stubs/mlton-stubs/platform.sig</span> add any new variants, as was done in the Basis Library.
</p>
</li>
<li>
<p>
In <span class="monospaced">lib/stubs/mlton-stubs/mlton.sml</span> add any new variants in <span class="monospaced">MLton.Platform</span>, as was done in the Basis Library.
</p>
</li>
</ul></div>
</div></div>
</li>
</ul></div>
<div class="paragraph"><p>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 <span class="monospaced">mlton/main/main.fun</span>, MLton itself uses the conversions to and
from strings:</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>MLton.Platform.{Arch,OS}.{from,to}String</pre>
</div></div>
<div class="paragraph"><p>If the there is a mismatch, you may see the error message
<span class="monospaced">strange arch</span> or <span class="monospaced">strange os</span>.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_running_the_regressions_with_a_cross_compiler">Running the regressions with a cross compiler</h2>
<div class="sectionbody">
<div class="paragraph"><p>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&#8217;s <span class="monospaced">-target</span> and <span class="monospaced">-stop g</span> flags, copying the generated files to
the target machine, then compiling and linking there.</p></div>
<div class="olist arabic"><ol class="arabic">
<li>
<p>
Remake the compiler on a working machine.
</p>
</li>
<li>
<p>
Use <span class="monospaced">bin/add-cross</span> to add support for the new target.  In particular, this should create <span class="monospaced">build/lib/mlton/targets/&lt;target&gt;/</span> with the platform-specific necessary cross-compilation information.
</p>
</li>
<li>
<p>
Run the regression tests with the cross-compiler.  To cross-compile all the tests, do
</p>
<div class="listingblock">
<div class="content monospaced">
<pre>bin/regression -cross &lt;target&gt;</pre>
</div></div>
<div class="paragraph"><p>This will create all the executables.  Then, copy <span class="monospaced">bin/regression</span> and
the <span class="monospaced">regression</span> directory to the target machine, and do</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>bin/regression -run-only &lt;target&gt;</pre>
</div></div>
<div class="paragraph"><p>This should run all the tests.</p></div>
</li>
</ol></div>
<div class="paragraph"><p>Repeat this step, interleaved with appropriate compiler modifications,
until all the regressions pass.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_bootstrap">Bootstrap</h2>
<div class="sectionbody">
<div class="paragraph"><p>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</p></div>
<div class="paragraph"><p>The <span class="monospaced">remote-bootstrap</span> goal of the root <span class="monospaced">Makefile</span> automates this process; see
comments in the root <span class="monospaced">Makefile</span>.  Here is an example bootstrapping on an OpenBSD
machine (named <span class="monospaced">thunder</span>):</p></div>
<div class="listingblock">
<div class="content monospaced">
<pre>$ make REMOTE_MACHINE=thunder REMOTE_MAKE=gmake REMOTE_MAKEFLAGS=WITH_GMP_DIR=/usr/local remote-bootstrap</pre>
</div></div>
<div class="paragraph"><p>Once you&#8217;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.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_also_see">Also see</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
<a href="http://www.mlton.org/pipermail/mlton/2002-October/013110.html">http://www.mlton.org/pipermail/mlton/2002-October/013110.html</a>
</p>
</li>
<li>
<p>
<a href="http://www.mlton.org/pipermail/mlton/2004-July/016029.html">http://www.mlton.org/pipermail/mlton/2004-July/016029.html</a>
</p>
</li>
<li>
<p>
<a href="https://github.com/MLton/mlton/issues/296">https://github.com/MLton/mlton/issues/296</a>
</p>
</li>
</ul></div>
</div>
</div>
</div>
<div id="footnotes"><hr></div>
<div id="footer">
<div id="footer-text">
</div>
<div id="footer-badges">
</div>
</div>
</body>
</html>
