|
|
CONVERSION ERROR
|
|
|
|
|
|
Error: HttpError (HttpExceptionRequest Request {
|
|
|
host = "ghc.haskell.org"
|
|
|
port = 443
|
|
|
secure = True
|
|
|
requestHeaders = []
|
|
|
path = "/trac/ghc/wiki/Building/Porting"
|
|
|
queryString = "?version=5"
|
|
|
method = "GET"
|
|
|
proxy = Nothing
|
|
|
rawBody = False
|
|
|
redirectCount = 10
|
|
|
responseTimeout = ResponseTimeoutDefault
|
|
|
requestVersion = HTTP/1.1
|
|
|
}
|
|
|
(StatusCodeException (Response {responseStatus = Status {statusCode = 403, statusMessage = "Forbidden"}, responseVersion = HTTP/1.1, responseHeaders = [("Date","Sun, 10 Mar 2019 06:57:47 GMT"),("Server","Apache/2.2.22 (Debian)"),("Strict-Transport-Security","max-age=63072000; includeSubDomains"),("Vary","Accept-Encoding"),("Content-Encoding","gzip"),("Content-Length","253"),("Content-Type","text/html; charset=iso-8859-1")], responseBody = (), responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose}) "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>403 Forbidden</title>\n</head><body>\n<h1>Forbidden</h1>\n<p>You don't have permission to access /trac/ghc/wiki/Building/Porting\non this server.</p>\n<hr>\n<address>Apache/2.2.22 (Debian) Server at ghc.haskell.org Port 443</address>\n</body></html>\n"))
|
|
|
|
|
|
Original source:
|
|
|
|
|
|
```trac
|
|
|
[[PageOutline]]
|
|
|
|
|
|
|
|
|
= Porting GHC =
|
|
|
|
|
|
This section describes how to port GHC to a currenly
|
|
|
unsupported platform. To avoid confusion, when we say
|
|
|
"architecture" we are referring to the processor, and
|
|
|
we use the term "platform" to refer to the combination
|
|
|
of architecture and operating system.
|
|
|
|
|
|
There are two distinct porting scenarios:
|
|
|
|
|
|
* Your platform is already supported, but you want to compile up GHC
|
|
|
using just a C compiler. This is a straightforward bootstrap from HC
|
|
|
files, and is described in the next section.
|
|
|
|
|
|
* Your platform isn't supported by GHC. You will need to do an
|
|
|
''unregisterised bootstrap'', proceed to
|
|
|
[[ref(Porting GHC to a new platform)]].
|
|
|
|
|
|
== Booting/porting from C ({{{.hc}}}) files ==
|
|
|
|
|
|
Bootstrapping GHC on a system without GHC already installed is
|
|
|
achieved by taking the intermediate C files (known as HC files) from
|
|
|
another GHC compilation, compiling them using gcc to get a working
|
|
|
GHC.
|
|
|
|
|
|
'''NOTE''': GHC versions 5.xx were hard to bootstrap from C. We
|
|
|
recommend using GHC 6.0.1 or later.
|
|
|
|
|
|
HC files are platform-dependent, so you have to get a set that were
|
|
|
generated on ''the same platform''. There may be some supplied on the
|
|
|
GHC download page, otherwise you'll have to compile some up yourself.
|
|
|
|
|
|
The following steps should result in a working GHC build with full
|
|
|
libraries:
|
|
|
|
|
|
* Make a set of HC files. On an identical system with GHC already
|
|
|
installed, get a GHC source tree and put the following in
|
|
|
{{{mk/build.mk}}}:
|
|
|
{{{
|
|
|
SRC_HC_OPTS = -H32m -O -fasm -Rghc-timing -keep-hc-files
|
|
|
GhcLibHcOpts = -O
|
|
|
GhcLibWays =
|
|
|
SplitObjs = NO
|
|
|
}}}
|
|
|
Build GHC as normal, and then {{{make hc-file-bundle Project=ghc}}}
|
|
|
to creates the tar file containing the hc files.
|
|
|
|
|
|
* On the target system, unpack the HC files on top of a fresh source
|
|
|
tree (make sure the source tree version matches the version of the
|
|
|
HC files ''exactly''!). This will place matching {{{.hc}}} files
|
|
|
next to the corresponding Haskell source ({{{.hs}}} or {{{.lhs}}})
|
|
|
in the compiler subdirectory {{{ghc/compiler}}} and in the
|
|
|
libraries (subdirectories of {{{libraries}}}).
|
|
|
|
|
|
* The actual build process is fully automated by the [[GhcFile(distrib/hc-build)]]
|
|
|
script. If you eventually
|
|
|
want to install GHC into the directory
|
|
|
`<dir>`, the following command will execute
|
|
|
the whole build process (it won't install yet):
|
|
|
{{{
|
|
|
$ distrib/hc-build --prefix=<dir>
|
|
|
}}}
|
|
|
By default, the installation directory is {{{/usr/local}}}. If
|
|
|
that is what you want, you may omit the argument to {{{hc-build}}}.
|
|
|
Generally, any option given to {{{hc-build}}} is passed through to
|
|
|
the configuration script {{{configure}}}. If {{{hc-build}}}
|
|
|
successfully completes the build process, you can install the
|
|
|
resulting system, as normal, with
|
|
|
{{{
|
|
|
$ make install
|
|
|
}}}
|
|
|
|
|
|
|
|
|
== Porting GHC to a new platform ==
|
|
|
|
|
|
The first step in porting to a new platform is to get an
|
|
|
''unregisterised'' 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:
|
|
|
|
|
|
* Global register variables: certain abstract machine "registers" are
|
|
|
mapped to real machine registers, depending on how many machine
|
|
|
registers are available (see [[GhcFile(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
|
|
|
[[GhcFile(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
|
|
|
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.
|
|
|
|
|
|
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
|
|
|
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 [mailto:glasgow-haskell-users@haskell.org].
|
|
|
|
|
|
Lots of useful information about the innards of GHC is available in
|
|
|
the [wiki:Commentary], which might be helpful if you run into some
|
|
|
code which needs tweaking for your system.
|
|
|
|
|
|
=== Cross-compiling to produce an unregisterised GHC ===
|
|
|
|
|
|
NOTE! These instructions apply to GHC 6.4 and (hopefully)
|
|
|
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 [http://www.haskell.org/ghc/ GHC homepage].
|
|
|
|
|
|
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.
|
|
|
|
|
|
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
|
|
|
''host'' machine), in order to cross-compile the
|
|
|
intermediate C files that we will use to bootstrap the compiler on the
|
|
|
''target'' machine.
|
|
|
|
|
|
'''On the target machine'''
|
|
|
|
|
|
Unpack a source tree (preferably a released
|
|
|
version). We will call the path to the root of this
|
|
|
tree `<T>`.
|
|
|
|
|
|
{{{
|
|
|
$ cd <T>
|
|
|
$ ./configure --enable-hc-boot --enable-hc-boot-unregisterised
|
|
|
}}}
|
|
|
|
|
|
You might need to update {{{configure.in}}} to recognise the new
|
|
|
platform, and re-generate {{{configure}}} with {{{autoreconf}}}.
|
|
|
|
|
|
{{{
|
|
|
$ cd <T>/includes
|
|
|
$ make
|
|
|
}}}
|
|
|
|
|
|
'''On the host machine'''
|
|
|
|
|
|
Unpack a source tree (same released version). Call this directory `<H>`.
|
|
|
|
|
|
{{{
|
|
|
$ cd <H>
|
|
|
$ ./configure
|
|
|
}}}
|
|
|
|
|
|
Create {{{<H>/mk/build.mk}}}, with the following contents:
|
|
|
|
|
|
{{{
|
|
|
GhcUnregisterised = YES
|
|
|
GhcLibHcOpts = -O -fvia-C -keep-hc-files
|
|
|
GhcRtsHcOpts = -keep-hc-files
|
|
|
GhcLibWays =
|
|
|
SplitObjs = NO
|
|
|
GhcWithNativeCodeGen = NO
|
|
|
GhcWithInterpreter = NO
|
|
|
GhcStage1HcOpts = -O
|
|
|
GhcStage2HcOpts = -O -fvia-C -keep-hc-files
|
|
|
SRC_HC_OPTS += -H32m
|
|
|
GhcBootLibs = YES
|
|
|
GhcWithSMP = NO
|
|
|
}}}
|
|
|
|
|
|
Edit {{{<H>/mk/config.mk}}}:
|
|
|
* change {{{TARGETPLATFORM}}} appropriately, and set the variables
|
|
|
involving {{{TARGET}}} or {{{Target}}} to the correct values for
|
|
|
the target platform. This step is necessary because
|
|
|
currently {{{configure}}} doesn't cope with specifying different
|
|
|
values for the {{{--host}}} and {{{--target}}} flags.
|
|
|
* copy {{{LeadingUnderscore}}} setting from target.
|
|
|
|
|
|
Copy {{{<T>/includes/ghcautoconf.h}}},
|
|
|
{{{<T>/includes/DerivedConstants.h}}}, and
|
|
|
{{{<T>/includes/GHCConstants.h}}} to {{{<H>/includes}}}.
|
|
|
Note that we are building on the host machine, using the
|
|
|
target machine's configuration files. This
|
|
|
is so that the intermediate C files generated here will
|
|
|
be suitable for compiling on the target system.
|
|
|
|
|
|
Touch the generated configuration files, just to make
|
|
|
sure they don't get replaced during the build:
|
|
|
{{{
|
|
|
$ cd <H>/includes
|
|
|
$ touch ghcautoconf.h DerivedConstants.h GHCConstants.h mkDerivedConstants.c
|
|
|
$ touch mkDerivedConstantsHdr mkDerivedConstants.o mkGHCConstants mkGHCConstants.o
|
|
|
}}}
|
|
|
|
|
|
Now build the compiler:
|
|
|
|
|
|
{{{
|
|
|
$ cd <H>/utils/mkdependC && make boot && make
|
|
|
$ cd <H>/includes && make boot && make
|
|
|
$ cd <H>/compat && make boot && make
|
|
|
$ cd <H>/utils && make boot && make
|
|
|
$ cd <H>/compiler && make boot && make
|
|
|
$ cd <H>/rts && make boot && make
|
|
|
}}}
|
|
|
|
|
|
Don't worry if the build falls over in the RTS, we don't need the RTS
|
|
|
yet.
|
|
|
|
|
|
{{{
|
|
|
$ cd <H>/libraries
|
|
|
$ make boot && make
|
|
|
}}}
|
|
|
|
|
|
{{{
|
|
|
$ cd <H>/compiler
|
|
|
$ make boot stage=2 && make stage=2
|
|
|
}}}
|
|
|
|
|
|
{{{
|
|
|
$ cd <H>/compat
|
|
|
$ make clean
|
|
|
$ 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'
|
|
|
}}}
|
|
|
|
|
|
{{{
|
|
|
$ cd <H>
|
|
|
$ make hc-file-bundle Project=Ghc<
|
|
|
}}}
|
|
|
|
|
|
Copy{{{<H>/*-hc.tar.gz}}} to {{{<T>/..}}}.
|
|
|
|
|
|
'''On the target machine'''
|
|
|
|
|
|
At this stage we simply need to bootstrap a compiler
|
|
|
from the intermediate C files we generated above. The
|
|
|
process of bootstrapping from C files is automated by the
|
|
|
script in {{{distrib/hc-build}}}, and is
|
|
|
described in [[ref(Booting/porting from C (.hc) files)]].
|
|
|
|
|
|
{{{
|
|
|
$ ./distrib/hc-build --enable-hc-boot-unregisterised
|
|
|
}}}
|
|
|
|
|
|
However, since this is a bootstrap on a new machine, the automated
|
|
|
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
|
|
|
tree; just use the compiler in that tree to build a fresh compiler
|
|
|
from scratch, this time without booting from C files. Before doing
|
|
|
this, you might want to check that the bootstrapped compiler is
|
|
|
generating working binaries:
|
|
|
|
|
|
{{{
|
|
|
$ cat >hello.hs
|
|
|
main = putStrLn "Hello World!\n"
|
|
|
^D
|
|
|
$ <T>/compiler/ghc-inplace hello.hs -o hello
|
|
|
$ ./hello
|
|
|
Hello World!
|
|
|
}}}
|
|
|
|
|
|
Once you have the unregisterised compiler up and running, you can use
|
|
|
it to start a registerised port. The following sections describe the
|
|
|
various parts of the system that will need architecture-specific
|
|
|
tweaks in order to get a registerised build going.
|
|
|
|
|
|
=== Porting the RTS ===
|
|
|
|
|
|
The following files need architecture-specific code for a registerised
|
|
|
build:
|
|
|
|
|
|
{{{includes/MachRegs.h}}}:
|
|
|
Defines the STG-register to machine-register
|
|
|
mapping. You need to know your platform's C calling
|
|
|
convention, and which registers are generally available
|
|
|
for mapping to global register variables. There are
|
|
|
plenty of useful comments in this file.
|
|
|
|
|
|
{{{includes/TailCalls.h}}}::
|
|
|
Macros that cooperate with the mangler (see [[ref(The mangler)]])
|
|
|
to make proper tail-calls work.
|
|
|
|
|
|
{{{rts/Adjustor.c}}}::
|
|
|
Support for {{{foreign import "wrapper"}}}.
|
|
|
Not essential for getting GHC bootstrapped, so this file
|
|
|
can be deferred until later if necessary.
|
|
|
|
|
|
{{{rts/StgCRun.c}}}::
|
|
|
The little assembly layer between the C world and
|
|
|
the Haskell world. See the comments and code for the
|
|
|
other architectures in this file for pointers.
|
|
|
|
|
|
{{{rts/MBlock.h}}}, {{{rts/MBlock.c}}}::
|
|
|
These files are really OS-specific rather than
|
|
|
architecture-specific. In {{{MBlock.h}}}
|
|
|
is specified the absolute location at which the RTS
|
|
|
should try to allocate memory on your platform (try to
|
|
|
find an area which doesn't conflict with code or dynamic
|
|
|
libraries). In {{{Mblock.c}}} you might
|
|
|
need to tweak the call to {{{mmap()}}} for
|
|
|
your OS.
|
|
|
|
|
|
=== The mangler ===
|
|
|
|
|
|
The mangler is an evil Perl-script
|
|
|
([[GhcFile(driver/mangler/ghc-asm.lprl)]]) that rearranges the assembly
|
|
|
code output from gcc. To understand what the manger does and how it works, see
|
|
|
[wiki:Commentary/EvilMangler].
|
|
|
|
|
|
The mangler is abstracted to a certain extent over some
|
|
|
architecture-specific things such as the particular assembler
|
|
|
directives used to herald symbols. Take a look at the definitions for
|
|
|
other architectures and use these as a starting point for porting it to
|
|
|
your platform.
|
|
|
|
|
|
=== The splitter ===
|
|
|
|
|
|
The splitter is another evil Perl script
|
|
|
([[GhcFile(driver/split/ghc-split.lprl)]]). It cooperates with the
|
|
|
mangler to support object splitting. Object splitting is what happens
|
|
|
when the {{{-split-objs}}} option is passed to GHC: the object file is
|
|
|
split into many smaller objects. This feature is used when building
|
|
|
libraries, so that a program statically linked against the library
|
|
|
will pull in less of the library.
|
|
|
|
|
|
The splitter has some platform-specific stuff; take a look and tweak
|
|
|
it for your system.
|
|
|
|
|
|
=== The native code generator ===
|
|
|
|
|
|
The native code generator isn't essential to getting a
|
|
|
registerised build going, but it's a desirable thing to have
|
|
|
because it can cut compilation times in half. The native code
|
|
|
generator is described in detail in [wiki:Commentary/BackEnds/NCG].
|
|
|
|
|
|
=== GHCi ===
|
|
|
|
|
|
To support GHCi, you need to port the dynamic linker
|
|
|
([[GhcFile(rts/Linker.c)]]). The linker currently supports the
|
|
|
ELF and PEi386 object file formats - if your platform uses one of
|
|
|
these then things will be significantly easier. The majority of Unix
|
|
|
platforms use the ELF format these days. Even so, there are some
|
|
|
machine-specific parts of the ELF linker: for example, the code for
|
|
|
resolving particular relocation types is machine-specific, so some
|
|
|
porting of this code to your architecture and/or OS will probaly be
|
|
|
necessary.
|
|
|
|
|
|
If your system uses a different object file format, then
|
|
|
you have to write a linker -- good luck!
|
|
|
# Porting GHC
|
|
|
|
|
|
|
|
|
This section describes how to port GHC to a currenly
|
|
|
unsupported platform. To avoid confusion, when we say
|
|
|
"architecture" we are referring to the processor, and
|
|
|
we use the term "platform" to refer to the combination
|
|
|
of architecture and operating system.
|
|
|
|
|
|
|
|
|
There are two distinct porting scenarios:
|
|
|
|
|
|
- Your platform is already supported, but you want to compile up GHC
|
|
|
using just a C compiler. This is a straightforward bootstrap from HC
|
|
|
files, and is described in the next section.
|
|
|
|
|
|
- Your platform isn't supported by GHC. You will need to do an
|
|
|
*unregisterised bootstrap*, proceed to
|
|
|
[Porting GHC to a new platform](#PortingGHCtoanewplatform).
|
|
|
|
|
|
## Booting/porting from C (`.hc`) files
|
|
|
|
|
|
|
|
|
Bootstrapping GHC on a system without GHC already installed is
|
|
|
achieved by taking the intermediate C files (known as HC files) from
|
|
|
another GHC compilation, compiling them using gcc to get a working
|
|
|
GHC.
|
|
|
|
|
|
**NOTE**: GHC versions 5.xx were hard to bootstrap from C. We
|
|
|
recommend using GHC 6.0.1 or later.
|
|
|
|
|
|
|
|
|
HC files are platform-dependent, so you have to get a set that were
|
|
|
generated on *the same platform*. There may be some supplied on the
|
|
|
GHC download page, otherwise you'll have to compile some up yourself.
|
|
|
|
|
|
|
|
|
The following steps should result in a working GHC build with full
|
|
|
libraries:
|
|
|
|
|
|
- Make a set of HC files. On an identical system with GHC already
|
|
|
installed, get a GHC source tree and put the following in
|
|
|
`mk/build.mk`:
|
|
|
|
|
|
```wiki
|
|
|
SRC_HC_OPTS = -H32m -O -fasm -Rghc-timing -keep-hc-files
|
|
|
GhcLibHcOpts = -O
|
|
|
GhcLibWays =
|
|
|
SplitObjs = NO
|
|
|
```
|
|
|
|
|
|
Build GHC as normal, and then `make hc-file-bundle Project=ghc`
|
|
|
to creates the tar file containing the hc files.
|
|
|
|
|
|
- On the target system, unpack the HC files on top of a fresh source
|
|
|
tree (make sure the source tree version matches the version of the
|
|
|
HC files *exactly*!). This will place matching `.hc` files
|
|
|
next to the corresponding Haskell source (`.hs` or `.lhs`)
|
|
|
in the compiler subdirectory `ghc/compiler` and in the
|
|
|
libraries (subdirectories of `libraries`).
|
|
|
|
|
|
- The actual build process is fully automated by the [distrib/hc-build](/trac/ghc/browser/ghc/distrib/hc-build)
|
|
|
script. If you eventually
|
|
|
want to install GHC into the directory
|
|
|
`<dir>`, the following command will execute
|
|
|
the whole build process (it won't install yet):
|
|
|
|
|
|
```wiki
|
|
|
$ distrib/hc-build --prefix=<dir>
|
|
|
```
|
|
|
|
|
|
By default, the installation directory is `/usr/local`. If
|
|
|
that is what you want, you may omit the argument to `hc-build`.
|
|
|
Generally, any option given to `hc-build` is passed through to
|
|
|
the configuration script `configure`. If `hc-build`
|
|
|
successfully completes the build process, you can install the
|
|
|
resulting system, as normal, with
|
|
|
|
|
|
```wiki
|
|
|
$ make install
|
|
|
```
|
|
|
|
|
|
## Porting GHC to a new platform
|
|
|
|
|
|
|
|
|
The first step in porting to a new platform is to get an
|
|
|
*unregisterised* 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:
|
|
|
|
|
|
- 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
|
|
|
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.
|
|
|
|
|
|
|
|
|
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
|
|
|
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 glasgow-haskell-users@….
|
|
|
|
|
|
|
|
|
Lots of useful information about the innards of GHC is available in
|
|
|
the [Commentary](commentary), which might be helpful if you run into some
|
|
|
code which needs tweaking for your system.
|
|
|
|
|
|
### Cross-compiling to produce an unregisterised GHC
|
|
|
|
|
|
|
|
|
NOTE! These instructions apply to GHC 6.4 and (hopefully)
|
|
|
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,
|
|
|
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.
|
|
|
|
|
|
|
|
|
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
|
|
|
*host* machine), in order to cross-compile the
|
|
|
intermediate C files that we will use to bootstrap the compiler on the
|
|
|
*target* machine.
|
|
|
|
|
|
**On the target machine**
|
|
|
|
|
|
|
|
|
Unpack a source tree (preferably a released
|
|
|
version). We will call the path to the root of this
|
|
|
tree `<T>`.
|
|
|
|
|
|
```wiki
|
|
|
$ cd <T>
|
|
|
$ ./configure --enable-hc-boot --enable-hc-boot-unregisterised
|
|
|
```
|
|
|
|
|
|
|
|
|
You might need to update `configure.ac` to recognise the new
|
|
|
platform, and re-generate `configure` with `autoreconf`.
|
|
|
|
|
|
```wiki
|
|
|
$ cd <T>/includes
|
|
|
$ make
|
|
|
```
|
|
|
|
|
|
**On the host machine**
|
|
|
|
|
|
|
|
|
Unpack a source tree (same released version). Call this directory `<H>`.
|
|
|
|
|
|
```wiki
|
|
|
$ cd <H>
|
|
|
$ ./configure
|
|
|
```
|
|
|
|
|
|
|
|
|
Create `<H>/mk/build.mk`, with the following contents:
|
|
|
|
|
|
```wiki
|
|
|
GhcUnregisterised = YES
|
|
|
GhcLibHcOpts = -O -fvia-C -keep-hc-files
|
|
|
GhcRtsHcOpts = -keep-hc-files
|
|
|
GhcLibWays =
|
|
|
SplitObjs = NO
|
|
|
GhcWithNativeCodeGen = NO
|
|
|
GhcWithInterpreter = NO
|
|
|
GhcStage1HcOpts = -O
|
|
|
GhcStage2HcOpts = -O -fvia-C -keep-hc-files
|
|
|
SRC_HC_OPTS += -H32m
|
|
|
GhcBootLibs = YES
|
|
|
GhcWithSMP = NO
|
|
|
```
|
|
|
|
|
|
|
|
|
Edit `<H>/mk/config.mk`:
|
|
|
|
|
|
- change `TARGETPLATFORM` appropriately, and set the variables
|
|
|
involving `TARGET` or `Target` to the correct values for
|
|
|
the target platform. This step is necessary because
|
|
|
currently `configure` doesn't cope with specifying different
|
|
|
values for the `--host` and `--target` flags.
|
|
|
- copy `LeadingUnderscore` setting from target.
|
|
|
|
|
|
|
|
|
Copy `<T>/includes/ghcautoconf.h`,
|
|
|
`<T>/includes/DerivedConstants.h`, and
|
|
|
`<T>/includes/GHCConstants.h` to `<H>/includes`.
|
|
|
Note that we are building on the host machine, using the
|
|
|
target machine's configuration files. This
|
|
|
is so that the intermediate C files generated here will
|
|
|
be suitable for compiling on the target system.
|
|
|
|
|
|
|
|
|
Touch the generated configuration files, just to make
|
|
|
sure they don't get replaced during the build:
|
|
|
|
|
|
```wiki
|
|
|
$ cd <H>/includes
|
|
|
$ touch ghcautoconf.h DerivedConstants.h GHCConstants.h mkDerivedConstants.c
|
|
|
$ touch mkDerivedConstantsHdr mkDerivedConstants.o mkGHCConstants mkGHCConstants.o
|
|
|
```
|
|
|
|
|
|
|
|
|
Now build the compiler:
|
|
|
|
|
|
```wiki
|
|
|
$ cd <H>/utils/mkdependC && make boot && make
|
|
|
$ cd <H>/includes && make boot && make
|
|
|
$ cd <H>/compat && make boot && make
|
|
|
$ cd <H>/utils && make boot && make
|
|
|
$ cd <H>/compiler && make boot && make
|
|
|
$ cd <H>/rts && make boot && make
|
|
|
```
|
|
|
|
|
|
|
|
|
Don't worry if the build falls over in the RTS, we don't need the RTS
|
|
|
yet.
|
|
|
|
|
|
```wiki
|
|
|
$ cd <H>/libraries
|
|
|
$ make boot && make
|
|
|
```
|
|
|
|
|
|
```wiki
|
|
|
$ cd <H>/compiler
|
|
|
$ make boot stage=2 && make stage=2
|
|
|
```
|
|
|
|
|
|
```wiki
|
|
|
$ cd <H>/compat
|
|
|
$ make clean
|
|
|
$ 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'
|
|
|
```
|
|
|
|
|
|
```wiki
|
|
|
$ cd <H>
|
|
|
$ make hc-file-bundle Project=Ghc<
|
|
|
```
|
|
|
|
|
|
|
|
|
Copy`<H>/*-hc.tar.gz` to `<T>/..`.
|
|
|
|
|
|
**On the target machine**
|
|
|
|
|
|
|
|
|
At this stage we simply need to bootstrap a compiler
|
|
|
from the intermediate C files we generated above. The
|
|
|
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
|
|
|
$ ./distrib/hc-build --enable-hc-boot-unregisterised
|
|
|
```
|
|
|
|
|
|
|
|
|
However, since this is a bootstrap on a new machine, the automated
|
|
|
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
|
|
|
tree; just use the compiler in that tree to build a fresh compiler
|
|
|
from scratch, this time without booting from C files. Before doing
|
|
|
this, you might want to check that the bootstrapped compiler is
|
|
|
generating working binaries:
|
|
|
|
|
|
```wiki
|
|
|
$ cat >hello.hs
|
|
|
main = putStrLn "Hello World!\n"
|
|
|
^D
|
|
|
$ <T>/compiler/ghc-inplace hello.hs -o hello
|
|
|
$ ./hello
|
|
|
Hello World!
|
|
|
```
|
|
|
|
|
|
|
|
|
Once you have the unregisterised compiler up and running, you can use
|
|
|
it to start a registerised port. The following sections describe the
|
|
|
various parts of the system that will need architecture-specific
|
|
|
tweaks in order to get a registerised build going.
|
|
|
|
|
|
### Porting the RTS
|
|
|
|
|
|
|
|
|
The following files need architecture-specific code for a registerised
|
|
|
build:
|
|
|
|
|
|
> `includes/MachRegs.h`:
|
|
|
>
|
|
|
> >
|
|
|
> > Defines the STG-register to machine-register
|
|
|
> > mapping. You need to know your platform's C calling
|
|
|
> > convention, and which registers are generally available
|
|
|
> > for mapping to global register variables. There are
|
|
|
> > plenty of useful comments in this file.
|
|
|
|
|
|
<table><tr><th>`includes/TailCalls.h`</th>
|
|
|
<td>
|
|
|
Macros that cooperate with the mangler (see [The mangler](#Themangler))
|
|
|
to make proper tail-calls work.
|
|
|
</td></tr></table>
|
|
|
|
|
|
<table><tr><th>`rts/Adjustor.c`</th>
|
|
|
<td>
|
|
|
Support for `foreign import "wrapper"`.
|
|
|
Not essential for getting GHC bootstrapped, so this file
|
|
|
can be deferred until later if necessary.
|
|
|
</td></tr></table>
|
|
|
|
|
|
<table><tr><th>`rts/StgCRun.c`</th>
|
|
|
<td>
|
|
|
The little assembly layer between the C world and
|
|
|
the Haskell world. See the comments and code for the
|
|
|
other architectures in this file for pointers.
|
|
|
</td></tr></table>
|
|
|
|
|
|
<table><tr><th>`rts/MBlock.h`, `rts/MBlock.c`</th>
|
|
|
<td>
|
|
|
These files are really OS-specific rather than
|
|
|
architecture-specific. In `MBlock.h`
|
|
|
is specified the absolute location at which the RTS
|
|
|
should try to allocate memory on your platform (try to
|
|
|
find an area which doesn't conflict with code or dynamic
|
|
|
libraries). In `Mblock.c` you might
|
|
|
need to tweak the call to `mmap()` for
|
|
|
your OS.
|
|
|
</td></tr></table>
|
|
|
|
|
|
### The mangler
|
|
|
|
|
|
|
|
|
The mangler is an evil Perl-script
|
|
|
([driver/mangler/ghc-asm.lprl](/trac/ghc/browser/ghc/driver/mangler/ghc-asm.lprl)) that rearranges the assembly
|
|
|
code output from gcc. To understand what the manger does and how it works, see
|
|
|
[Commentary/EvilMangler](commentary/evil-mangler).
|
|
|
|
|
|
|
|
|
The mangler is abstracted to a certain extent over some
|
|
|
architecture-specific things such as the particular assembler
|
|
|
directives used to herald symbols. Take a look at the definitions for
|
|
|
other architectures and use these as a starting point for porting it to
|
|
|
your platform.
|
|
|
|
|
|
### The splitter
|
|
|
|
|
|
|
|
|
The splitter is another evil Perl script
|
|
|
([driver/split/ghc-split.lprl](/trac/ghc/browser/ghc/driver/split/ghc-split.lprl)). It cooperates with the
|
|
|
mangler to support object splitting. Object splitting is what happens
|
|
|
when the `-split-objs` option is passed to GHC: the object file is
|
|
|
split into many smaller objects. This feature is used when building
|
|
|
libraries, so that a program statically linked against the library
|
|
|
will pull in less of the library.
|
|
|
|
|
|
|
|
|
The splitter has some platform-specific stuff; take a look and tweak
|
|
|
it for your system.
|
|
|
|
|
|
### The native code generator
|
|
|
|
|
|
|
|
|
The native code generator isn't essential to getting a
|
|
|
registerised build going, but it's a desirable thing to have
|
|
|
because it can cut compilation times in half. The native code
|
|
|
generator is described in detail in Commentary/BackEnds/NCG?.
|
|
|
|
|
|
### GHCi
|
|
|
|
|
|
|
|
|
To support GHCi, you need to port the dynamic linker
|
|
|
([rts/Linker.c](/trac/ghc/browser/ghc/rts/Linker.c)). The linker currently supports the
|
|
|
ELF and PEi386 object file formats - if your platform uses one of
|
|
|
these then things will be significantly easier. The majority of Unix
|
|
|
platforms use the ELF format these days. Even so, there are some
|
|
|
machine-specific parts of the ELF linker: for example, the code for
|
|
|
resolving particular relocation types is machine-specific, so some
|
|
|
porting of this code to your architecture and/or OS will probaly be
|
|
|
necessary.
|
|
|
|
|
|
|
|
|
If your system uses a different object file format, then
|
|
|
you have to write a linker -- good luck! |