You've been rash enough to want to build some of the Glasgow Functional Programming tools (GHC, Happy, nofib, etc) from source. You've slurped the source, from the CVS repository or from a source distribution, and now you're sitting looking at a huge mound of bits, wondering what to do next.
Gingerly, you type
make all. Wrong already!
This rest of this guide is intended for duffers like me, who aren't really interested in Makefiles and systems configurations, but who need a mental model of the interlocking pieces so that they can make them work, extend them consistently when adding new software, and lay hands on them gently when they don't work.
The source code is held in your source tree. The root directory of your source tree must contain the following directories and files:
Makefile: the root Makefile.
mk/: the directory that contains the main Makefile code, shared by all the
config.guess: these files support the configuration process.
All the other directories are individual projects of the
fptools system --- for example, the Glasgow Haskell Compiler
ghc), the Happy parser generator (
suite, and so on. You can have zero or more of these. Needless to
say, some of them are needed to build others.
The important thing to remember is that even if you want only one
happy, say), you must have a source tree whose root
configure.in, and the
project(s) you want (
happy/ in this case). You cannot get by with
While you can build a system in the source tree, we don't recommend it. We often want to build multiple versions of our software for different architectures, or with different options (e.g. profiling). It's very desirable to share a single copy of the source code among all these builds.
So for every source tree we have zero or more build trees. Each
build tree is initially an exact copy of the source tree, except that
each file is a symbolic link to the source file, rather than being a
copy of the source file. There are ``standard'' Unix utilities that
make such copies, so standard that they go by different names:
are two (If you
don't have either, the source distribution includes sources for the
lndir --- check out
The build tree does not need to be anywhere near the source tree in the file system. Indeed, one advantage of separating the build tree from the source is that the build tree can be placed in a non-backed-up partition, saving your systems support people from backing up untold megabytes of easily-regenerated, and rapidly-changing, gubbins. The golden rule is that (with a single exception -- Section Build Configuration absolutely everything in the build tree is either a symbolic link to the source tree, or else is mechanically generated. It should be perfectly OK for your build tree to vanish overnight; an hour or two compiling and you're on the road again.
You need to be a bit careful, though, that any new files you create (if you do any development work) are in the source tree, not a build tree!
Remember, that the source files in the build tree are symbolic
links to the files in the source tree. (The build tree soon
accumulates lots of built files like
Foo.o, as well.) You
can delete a source file from the build tree without affecting
the source tree (though it's an odd thing to do). On the other hand,
if you edit a source file from the build tree, you'll edit the
source-tree file directly. (You can set up Emacs so that if you edit
a source file from the build tree, Emacs will silently create an
edited copy of the source file in the build tree, leaving the source
file unchanged; but the danger is that you think you've edited the
source file whereas actually all you've done is edit the build-tree
copy. More commonly you do want to edit the source file.)
Like the source tree, the top level of your build tree must (a linked
copy of) the root directory of the
fptools suite. Inside Makefiles,
the root of your build tree is called
. In the rest of this document path
names are relative to
$(FPTOOLS_TOP) unless otherwise stated. For
example, the file
ghc/mk/target.mk is actually
When you build
fptools you will be compiling code on a particular
host platform, to run on a particular target platform
(usually the same as the host platform)
difficulty is that there are minor differences between different
platforms; minor, but enough that the code needs to be a bit different
for each. There are some big differences too: for a different
architecture we need to build GHC with a different native-code
There are also knobs you can turn to control how the
software is built. For example, you might want to build GHC optimised
(so that it runs fast) or unoptimised (so that you can compile it fast
after you've modified it. Or, you might want to compile it with
debugging on (so that extra consistency-checking code gets included)
or off. And so on.
All of this stuff is called the configuration of your build. You set the configuration using an exciting three-step process.
Change directory to
$(FPTOOLS_TOP) and issue the command
no arguments). This GNU program converts
to a shell script called
Both these steps are completely platform-independent; they just mean
that the human-written file (
configure.in) can be short, although
the resulting shell script,
In case you don't have
autoconf we distribute the results,
mk/config.h.in, with the source distribution. They
aren't kept in the repository, though.
Runs the newly-created
configure script, thus:
configure's mission is to scurry round your computer working out what architecture it has, what operating system, whether it has the
vforksystem call, where
yaccis kept, whether
gccis available, where various obscure
#includefiles are, whether it's a leap year, and what the systems manager had for lunch. It communicates these snippets of information in two ways:
mk/config.mk, substituting for things between ``@@@@}'' brackets. So, ``@HaveGcc@'' will be replaced by ``
YES'' or ``
NO'' depending on what
mk/config.mkis included by every Makefile (directly or indirectly), so the configuration information is thereby communicated to all Makefiles.
mk/config.h. The latter is
#included by various C programs, which can thereby make use of configuration information.
configure caches the results of its run in
often you don't want that; you're running
configure a second time
because something has changed. In that case, simply delete
Next, you say how this build of
fptools is to differ from the
standard defaults by creating a new file
in the build tree. This file is the one and only file you edit
in the build tree, precisely because it says how this build differs
from the source. (Just in case your build tree does die, you might
want to keep a private directory of
build.mk files, and use a
symbolic link in each build tree to point to the appropriate one.) So
mk/build.mk never exists in the source tree --- you create one in
each build tree from the template. We'll discuss what to put in it
And that's it for configuration. Simple, eh?
What do you put in your build-specific configuration file
mk/build.mk? For almost all purposes all you will do is put
make variable definitions that override those in
The whole point of
mk/config.mk.in --- and its derived counterpart
mk/config.mk --- is to define the build configuration. It is heavily
commented, as you will see if you look at it. So generally, what you
do is look at
mk/config.mk.in, and add definitions in
that override any of the
config.mk definitions that you want to
change. (The override occurs because the main boilerplate file,
config.mk.in contains the definition:
ProjectsToBuild = glafp-utils ghc
The accompanying comment explains that this is the list of enabled
projects; that is, if (after configuring) you type
gmake all in
FPTOOLS_TOP four specified projects will be made. If you want to
green-card, you can add this line to
ProjectsToBuild += green-card
or, if you prefer,
ProjectsToBuild = glafp-utils ghc green-card
make allows existing definitions to have new text appended
using the ``
+='' operator, which is quite a convenient feature.)
config.mk.in, remember that anything between
``@...@'' signs is going to be substituted by
later. You can override the resulting definition if you want,
but you need to be a bit surer what you are doing. For example,
there's a line that says:
YACC = @YaccCmd@
This defines the Make variables
YACC to the pathname for a Yacc that
configure finds somewhere. If you have your own pet Yacc you want
to use instead, that's fine. Just add this line to
YACC = myyacc
You do not have to have a
mk/build.mk file at all; if you
don't, you'll get all the default settings from
You can also use
build.mk to override anything that
wrong. One place where this happens often is with the definition of
FPTOOLS_TOP_ABS: this variable is supposed to be the canonical path
to the top of your source tree, but if your system uses an automounter
then the correct directory is hard to find automatically. If you find
configure has got it wrong, just put the correct definition in
Let's summarise the steps you need to carry to get yourself a fully-configured build tree from scratch.
myfptools(it does not have to be called
fptools). Make sure that you have the essential files (see Section Source Tree).
mkshadowdirto create a build tree.
You probably want to give the build tree a name that suggests its main defining characteristic (in your mind at least), in case you later add others.
cd myfptools mkshadowdir . /scratch/joe-bloggs/myfptools-sun4
(You can skip this step if you are starting from a source distribution, and you already have
mk/build.mk, adding definitions for your desired configuration options.
mk/build.mkas often as you like. You do not have to run any further configuration programs to make these changes take effect. In theory you should, however, say
gmake all, because configuration option changes could affect anything --- but in practice you are likely to know what's affected.
At this point you have made yourself a fully-configured build tree, so you are ready to start building real things.
The first thing you need to know is that
you must use GNU
make, usually called
gmake, not standard Unix
If you use standard Unix
make you will get all sorts of error messages
(but no damage) because the
Makefiles use GNU
In any directory you should be able to make the following:
does the one-off preparation required to get ready for the real work.
Notably, it does
gmake depend in all directories that contain
boot does more. For example, you can't do
depend in a directory of C program until you have converted the
.lh header files into standard
.h header files.
Similarly, you can't convert a literate file to illiterate form until
you have built the
boot takes care of these
You should say
gmake boot right after configuring your build tree,
but note that this is a one-off, i.e., there's no need to re-do
gmake boot if you should re-configure your build tree at a later
stage (no harm caused if you do though).
makes all the final target(s) for this Makefile.
Depending on which directory you are in a ``final target'' may be an
executable program, a library archive, a shell script, or a Postscript
gmake alone is generally the same as typing
installs the things built by
all. Where does it
install them? That is specified by
mk/config.mk.in; you can
override it in
reverses the effect of
remove all easily-rebuilt files.
remove all files that can be rebuilt at all. There's a danger here that you may remove a file that needs a more obscure utility to rebuild it (especially if you started from a source distribution).
run the test suite.
All of these standard targets automatically recurse into sub-directories. Certain other standard targets do not:
is only available in the root directory
$(FPTOOLS_TOP); it has been discussed in Section
.depend file in each directory that needs
.depend file contains mechanically-generated dependency
information; for example, suppose a directory contains a Haskell
Foo.lhs which imports another module
Then the generated
.depend file will contain the dependency:
Foo.o : Baz.hi
which says that the object file
Foo.o depends on the interface file
Baz.hi generated by compiling module
.depend file is
automatically included by every Makefile.
make a binary distribution. This is the target we use to build the binary distributions of GHC and Happy.
make a source distribution. You must be in a linked buid tree to make this target.
Makefiles have targets other than these. You can find
this out by looking in the
Sometimes the dependencies get in the way: if you've made a small
change to one file, and you're absolutely sure that it won't affect
anything else, but you know that
make is going to rebuid everything
anyway, the following hack may be useful:
This tells the make system to ignore dependencies and just build what
you tell it to. In other words, it's equivalent to temporarily
.depend file in the current directory (where
mkdependHS and friends store their dependency information).
A bit of history: GHC used to come with a
fastmake script that did
the above job, but GNU make provides the features we need to do it
without resorting to a script. Also, we've found that fastmaking is
less useful since the advent of GHC's recompilation checker (see the
User's Guide section on "Separate Compilation").