Instructions for 6.11 authored by ian@well-typed.com's avatar ian@well-typed.com
...@@ -82,39 +82,21 @@ libraries: ...@@ -82,39 +82,21 @@ libraries:
## Porting GHC to a new platform ## Porting GHC to a new platform
**NOTE**: Versions supported: between 6.0.1 and 6.6.2. We are working **NOTE**: Versions supported: 6.11+.
on getting bootstrapping working again in the 6.8 series, see [\#1346](https://gitlab.haskell.org//ghc/ghc/issues/1346).
The first step in porting to a new platform is to get an The first step in porting to a new platform is to get an
*unregisterised* build working. An unregisterised build is one that *unregisterised* build working. An unregisterised build is one that
compiles via vanilla C only. By contrast, a registerised build uses compiles via vanilla C only. Tist costs about a factor of two in
the following architecture-specific hacks for speed: performance, but since unregisterised compilation is usually just a step
on the way to a full registerised port, we don't mind too much.
- Global register variables: certain abstract machine "registers" are
mapped to real machine registers, depending on how many machine
registers are available (see [includes/MachRegs.h](/trac/ghc/browser/ghc/includes/MachRegs.h)).
- Assembly-mangling: when compiling via C, we feed the assembly
generated by gcc though a Perl script known as the *mangler* (see
[driver/mangler/ghc-asm.lprl](/trac/ghc/browser/ghc/driver/mangler/ghc-asm.lprl). The mangler rearranges
the assembly to support tail-calls and various other optimisations.
In an unregisterised build, neither of these hacks are You should go through this process even if your architecture is already
used -- the idea is that the C code generated by the has registerised support in GHC, but your OS currently isn't supported.
compiler should compile using gcc only. The lack of these In this case you probably won't need to port any of the
optimisations costs about a factor of two in performance, but architecture-specific parts of the code, and you can proceed straight
since unregisterised compilation is usually just a step on the from the unregisterised build to build a registerised compiler.
way to a full registerised port, we don't mind too much.
You should go through this process even if your
architecture is already has registerised support in GHC, but
your OS currently isn't supported. In this case you probably
won't need to port any of the architecture-specific parts of the
code, and you can proceed straight from the unregisterised build
to build a registerised compiler.
Notes on GHC portability in general: we've tried to stick Notes on GHC portability in general: we've tried to stick
...@@ -132,11 +114,7 @@ code which needs tweaking for your system. ...@@ -132,11 +114,7 @@ code which needs tweaking for your system.
### Cross-compiling to produce an unregisterised GHC ### Cross-compiling to produce an unregisterised GHC
NOTE! These instructions apply to GHC 6.4 and (hopefully) NOTE! These instructions apply to GHC 6.11 and (hopefully) later.
later. If you need instructions for an earlier version of GHC, try
to get hold of the version of this document that was current at the
time. It should be available from the appropriate download page on
the [GHC homepage](http://www.haskell.org/ghc/).
In this section, we explain how to bootstrap GHC on a new platform, In this section, we explain how to bootstrap GHC on a new platform,
...@@ -148,10 +126,9 @@ to cope with minor porting issues anyway. ...@@ -148,10 +126,9 @@ to cope with minor porting issues anyway.
The following step-by-step instructions should result in a fully The following step-by-step instructions should result in a fully
working, albeit unregisterised, GHC. Firstly, you need a machine that working, albeit unregisterised, GHC. Firstly, you need a machine that
already has a working GHC (we'll call this the already has a working GHC (we'll call this the *host* machine), in
*host* machine), in order to cross-compile the order to cross-compile the intermediate C files that we will use to
intermediate C files that we will use to bootstrap the compiler on the bootstrap the compiler on the *target* machine.
*target* machine.
**On the target machine** **On the target machine**
...@@ -162,7 +139,8 @@ tree `<T>`. ...@@ -162,7 +139,8 @@ tree `<T>`.
```wiki ```wiki
$ cd <T> $ cd <T>
$ ./configure --enable-hc-boot --enable-hc-boot-unregisterised $ sh boot
$ ./configure --enable-hc-boot
``` ```
...@@ -170,8 +148,7 @@ You might need to update `configure.ac` to recognise the new ...@@ -170,8 +148,7 @@ You might need to update `configure.ac` to recognise the new
platform, and re-generate `configure` with `autoreconf`. platform, and re-generate `configure` with `autoreconf`.
```wiki ```wiki
$ cd <T>/includes $ make bootstrapping-files
$ make
``` ```
**On the host machine** **On the host machine**
...@@ -181,6 +158,7 @@ Unpack a source tree (same released version, with the extra libs). Call this di ...@@ -181,6 +158,7 @@ Unpack a source tree (same released version, with the extra libs). Call this di
```wiki ```wiki
$ cd <H> $ cd <H>
$ sh boot
$ ./configure $ ./configure
``` ```
...@@ -191,19 +169,18 @@ Create `<H>/mk/build.mk`, with the following contents: ...@@ -191,19 +169,18 @@ Create `<H>/mk/build.mk`, with the following contents:
GhcUnregisterised = YES GhcUnregisterised = YES
GhcLibHcOpts = -O -fvia-C -keep-hc-files GhcLibHcOpts = -O -fvia-C -keep-hc-files
GhcRtsHcOpts = -keep-hc-files GhcRtsHcOpts = -keep-hc-files
GhcLibWays = GhcLibWays = v
SplitObjs = NO SplitObjs = NO
GhcWithNativeCodeGen = NO GhcWithNativeCodeGen = NO
GhcWithInterpreter = NO GhcWithInterpreter = NO
GhcStage1HcOpts = -O GhcStage1HcOpts = -O
GhcStage2HcOpts = -O -fvia-C -keep-hc-files GhcStage2HcOpts = -O -fvia-C -keep-hc-files
SRC_HC_OPTS += -H32m SRC_HC_OPTS += -H32m
GhcBootLibs = YES
GhcWithSMP = NO GhcWithSMP = NO
``` ```
Edit `<H>/mk/config.mk`: Edit `<H>/mk/project.mk`:
- change `TARGETPLATFORM` appropriately, and set the variables - change `TARGETPLATFORM` appropriately, and set the variables
involving `TARGET` or `Target` to the correct values for involving `TARGET` or `Target` to the correct values for
...@@ -222,76 +199,90 @@ is so that the intermediate C files generated here will ...@@ -222,76 +199,90 @@ is so that the intermediate C files generated here will
be suitable for compiling on the target system. be suitable for compiling on the target system.
Touch the generated configuration files, just to make Now build the compiler:
sure they don't get replaced during the build:
```wiki ```wiki
$ cd <H>/includes $ make
$ touch ghcautoconf.h DerivedConstants.h GHCConstants.h mkDerivedConstants.c
$ touch mkDerivedConstantsHdr mkDerivedConstants.o mkGHCConstants mkGHCConstants.o
``` ```
Now build the compiler: You may need to work around problems that occur due to differences
between the host and target platforms.
```wiki ```wiki
$ cd <H>/utils/mkdependC && make boot && make $ cd <H>
$ cd <H>/includes && make boot && make $ rm -f list mkfiles boot.tar.gz
$ cd <H>/compat && make boot && make $ find . -name "*.hc" >> list
$ cd <H>/utils && make boot && make $ find . -name "*_stub.*" >> list
$ cd <H>/compiler && make boot && make $ find . -name package-data.mk >> list
$ cd <H>/rts && make boot && make $ find . -name package.conf >> list
$ cd <H>/libraries $ find . -name package.conf.inplace >> list
$ make boot && make $ echo compiler/main/Config.hs >> list
$ find . -name .depend | sed -e 's/^/mkdir -p `dirname /' -e 's/$/`/' >> mkfiles
$ find . -name .depend | sed "s/^/touch /" >> mkfiles
$ echo mkfiles >> list
$ tar -zcf boot.tar.gz -T list
``` ```
**On the target machine**
```wiki ```wiki
$ cd <H>/compiler $ cd <T>
$ make boot stage=2 && make stage=2 $ cp /bin/pwd utils/ghc-pwd/ghc-pwd
``` ```
```wiki ```wiki
$ cd <H>/compat $ sh boot
$ make clean $ ./configure --enable-hc-boot
$ rm .depend
$ make boot UseStage1=YES EXTRA_HC_OPTS='-O -fvia-C -keep-hc-files'
$ cd <H>/utils
$ make clean
$ make -k UseStage1=YES EXTRA_HC_OPTS='-O -fvia-C -keep-hc-files'
``` ```
Unpack `<H>/boot.tar.gz` to `<T>/`.
```wiki ```wiki
$ cd <H> $ tar --touch -zxf boot.tar.gz
$ make hc-file-bundle Project=Ghc $ sh mkfiles
``` ```
Unpack `<H>/*-hc.tar.gz` to `<T>/..`. Put this in `<T>/mk/build.mk`:
```wiki ```wiki
$ tar xzf <H>/*-hc.tar.gz -C <T>/.. GHC = false
GHC_PKG_INPLACE =
GHC_CABAL_INPLACE =
DUMMY_GHC_INPLACE =
UNLIT =
NO_INCLUDE_DEPS = YES
GhcUnregisterised = YES
GhcLibWays = v
SplitObjs = NO
GhcWithNativeCodeGen = NO
GhcWithInterpreter = NO
GhcWithSMP = NO
ghc_stage2_v_EXTRA_CC_OPTS += -Lgmp -lgmp -lm -lutil -lrt
``` ```
**On the target machine** ```wiki
$ for c in libraries/*/configure; do ( cd `dirname $c`; ./configure ); done
```
```wiki
$ sed -i .bak "s/<H>/<T>/g" */*/package-data.mk */*/*/package-data.mk
$ touch -r compiler/stage2/package-data.mk */*/package-data.mk */*/*/package-data.mk
```
At this stage we simply need to bootstrap a compiler Now make bootstrapping files; what we're really doing here is making
from the intermediate C files we generated above. The libffi, and libgmp if necessary:
process of bootstrapping from C files is automated by the
script in `distrib/hc-build`, and is
described in [Booting/porting from C (.hc) files](#Booting/portingfromC(.hc)files).
```wiki ```wiki
$ ./distrib/hc-build --enable-hc-boot-unregisterised $ make bootstrapping-files
``` ```
```wiki
However, since this is a bootstrap on a new machine, the automated $ make all_ghc_stage2 2>&1 | tee log
process might not run to completion the first time. For that reason, ```
you might want to treat the `hc-build` script as a list of
instructions to follow, rather than as a fully automated script. This
way you'll be able to restart the process part-way through if you need
to fix anything on the way.
Don't bother with running `make install` in the newly bootstrapped Don't bother with running `make install` in the newly bootstrapped
...@@ -304,7 +295,7 @@ generating working binaries: ...@@ -304,7 +295,7 @@ generating working binaries:
$ cat >hello.hs $ cat >hello.hs
main = putStrLn "Hello World!\n" main = putStrLn "Hello World!\n"
^D ^D
$ <T>/compiler/ghc-inplace hello.hs -o hello $ <T>/inplace/bin/ghc-stage2 hello.hs -o hello
$ ./hello $ ./hello
Hello World! Hello World!
``` ```
... ...
......