+ <listitem>
+ <para>The actual build process is fully automated by the
+ <filename>hc-build</filename> script located in the
+ <filename>distrib</filename> directory. If you eventually
+ want to install GHC into the directory
+ <replaceable>dir</replaceable>, the following
+ command will execute the whole build process (it won't
+ install yet):</para>
+
+<Screen>
+foo% distrib/hc-build --prefix=<replaceable>dir</replaceable>
+</Screen>
+<indexterm><primary>--hc-build</primary></indexterm>
+
+ <para>By default, the installation directory is
+ <filename>/usr/local</filename>. If that is what you want,
+ you may omit the argument to <filename>hc-build</filename>.
+ Generally, any option given to <filename>hc-build</filename>
+ is passed through to the configuration script
+ <filename>configure</filename>. If
+ <filename>hc-build</filename> successfully completes the
+ build process, you can install the resulting system, as
+ normal, with</para>
+
+<Screen>
+foo% make install
+</Screen>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2 id="unregisterised-porting">
+ <title>Porting GHC to a new architecture</title>
+
+ <para>The first step in porting to a new architecture is to get
+ an <firstterm>unregisterised</firstterm> build working. An
+ unregisterised build is one that compiles via vanilla C only.
+ By contrast, a registerised build uses the following
+ architecture-specific hacks for speed:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Global register variables: certain abstract machine
+ <quote>registers</quote> are mapped to real machine
+ registers, depending on how many machine registers are
+ available (see
+ <filename>ghc/includes/MachRegs.h</filename>).</para>
+ </listitem>
+
+ <listitem>
+ <para>Assembly-mangling: when compiling via C, we feed the
+ assembly generated by gcc though a Perl script known as the
+ <firstterm>mangler</firstterm> (see
+ <filename>ghc/driver/mangler/ghc-asm.lprl</filename>). The
+ mangler rearranges the assembly to support tail-calls and
+ various other optimisations.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>In an unregisterised build, neither of these hacks are
+ used — the idea is that the C code generated by the
+ compiler should compile using gcc only. The lack of these
+ optimisations costs about a factor of two in performance, but
+ since unregisterised compilation is usually just a step on the
+ way to a full registerised port, we don't mind too much.</para>
+
+ <para>Notes on GHC portability in general: we've tried to stick
+ to writing portable code in most parts of the system, so it
+ should compile on any POSIXish system with gcc, but in our
+ experience most systems differ from the standards in one way or
+ another. Deal with any problems as they arise - if you get
+ stuck, ask the experts on
+ <email>glasgow-haskell-users@haskell.org</email>.</para>
+
+ <para>Lots of useful information about the innards of GHC is
+ available in the <ulink
+ url="http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/">GHC
+ Commentary</ulink>, which might be helpful if you run into some
+ code which needs tweaking for your system.</para>
+
+ <sect3>
+ <title>Cross-compiling to produce an unregisterised GHC</title>
+
+ <para>In this section, we explain how to bootstrap GHC on a
+ new platform, using unregisterised intermediate C files. We
+ haven't put a great deal of effort into automating this
+ process, for two reasons: it is done very rarely, and the
+ process usually requires human intervention to cope with minor
+ porting issues anyway.</para>
+
+ <para>The following step-by-step instructions should result in
+ a fully working, albeit unregisterised, GHC. Firstly, you
+ need a machine that already has a working GHC (we'll call this
+ the <firstterm>host</firstterm> machine), in order to
+ cross-compile the intermediate C files that we will use to
+ bootstrap the compiler on the <firstterm>target</firstterm>
+ machine.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>On the target machine:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Unpack a source tree (preferably a released
+ version). We will call the path to the root of this
+ tree <replaceable>T</replaceable>.</para>
+ </listitem>
+
+ <listitem>
+<screen>
+$ cd <replaceable>T</replaceable>
+$ ./configure --enable-hc-boot --enable-hc-boot-unregisterised
+</screen>
+
+ <para>You might need to update
+ <filename>configure.in</filename> to recognise the new
+ architecture, and re-generate
+ <filename>configure</filename> with
+ <literal>autoreconf</literal>.</para>
+ </listitem>
+
+ <listitem>
+<screen>
+$ cd <replaceable>T</replaceable>/ghc/includes
+$ make config.h
+</screen>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>On the host machine:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Unpack a source tree (same released version). Call
+ this directory <replaceable>H</replaceable>.</para>
+ </listitem>
+
+ <listitem>
+<screen>
+$ cd <replaceable>H</replaceable>
+$ ./configure
+</screen>
+ </listitem>
+
+ <listitem>
+ <para>Create
+ <filename><replaceable>H</replaceable>/mk/build.mk</filename>,
+ with the following contents:</para>
+
+<programlisting>
+GhcUnregisterised = YES
+GhcLibHcOpts = -O -H32m -keep-hc-files
+GhcLibWays =
+SplitObjs = NO
+GhcWithNativeCodeGen = NO
+GhcWithInterpreter = NO
+GhcStage1HcOpts = -O -H32m -fasm
+GhcStage2HcOpts = -O -fvia-C -keep-hc-files
+</programlisting>
+ </listitem>
+
+ <listitem>
+ <para>Edit
+ <filename><replaceable>H</replaceable>/mk/config.mk</filename>:</para>
+ <itemizedlist>
+ <listitem>
+ <para>change <literal>TARGETPLATFORM</literal>
+ appropriately, and set the variables involving
+ <literal>TARGET</literal> to the correct values for
+ the target platform. This step is necessary because
+ currently <literal>configure</literal> doesn't cope
+ with specifying different values for the
+ <literal>--host</literal> and
+ <literal>--target</literal> flags.</para>
+ </listitem>
+ <listitem>
+ <para>copy <literal>LeadingUnderscore</literal>
+ setting from target.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>Copy
+ <filename><replaceable>T</replaceable>/ghc/includes/config.h</filename>
+ to
+ <filename><replaceable>H</replaceable>/ghc/includes</filename>.
+ Note that we are building on the host machine, using the
+ target machine's <literal>config.h</literal> file. This
+ is so that the intermediate C files generated here will
+ be suitable for compiling on the target system.</para>
+
+ </listitem>
+
+ <listitem>
+ <para>Touch <literal>config.h</literal>, just to make
+ sure it doesn't get replaced during the build:</para>
+<screen>
+$ touch <replaceable>H</replaceable>/ghc/includes/config.h</screen>
+ </listitem>
+
+ <listitem>
+ <para>Now build the compiler:</para>
+<screen>
+$ cd <replaceable>H</replaceable>/glafp-utils && make boot && make
+$ cd <replaceable>H</replaceable>/ghc && make boot && make
+</screen>
+ <para>Don't worry if the build falls over in the RTS, we
+ don't need the RTS yet.</para>
+ </listitem>
+
+ <listitem>
+<screen>
+$ cd <replaceable>H</replaceable>/libraries
+$& make boot && make
+</screen>
+ </listitem>
+
+ <listitem>
+<screen>
+$ cd <replaceable>H</replaceable>/ghc
+$ make boot stage=2 && make stage=2
+</screen>
+ </listitem>
+
+ <listitem>
+ <screen>
+$ cd <replaceable>H</replaceable>/ghc/utils
+$ make clean
+$ make -k HC=<replaceable>H</replaceable>/ghc/compiler/stage1/ghc-inplace \
+ EXTRA_HC_OPTS='-O -fvia-C -keep-hc-files'
+</screen>
+ </listitem>
+
+ <listitem>
+<screen>
+$ cd <replaceable>H</replaceable>
+$ make hc-file-bundle Project=Ghc
+</screen>
+ </listitem>
+
+ <listitem>
+ <para>copy
+ <filename><replaceable>H</replaceable>/*-hc.tar.gz</filename>
+ to <filename><replaceable>T</replaceable>/..</filename>.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>