A package author must fulfil the specification of Section 4. In many cases, a Haskell package will consist of nothing more than a bunch of Haskell modules, with perhaps the odd C file. In that case, the HPS provides a simple build infrastructure that fulfils the specification of Section 4, and provides some modest further facilities besides.
This simple build infrastructure is meant to automate the common case. (Think hmake.) The emphasis is on ``simple'': if you want something more elaborate, you can (a) modify the simple build infrastructure (which is written in Haskell) (b) use makefiles, or (c) implement something else entirely.
The simple build infrastructure works as follows. First, Angela puts the following Haskell file Setup.lhs in the root of her tree:
#! runghc > import Distribution.SimpleSecond, she writes a package description pkg.desc in the syntax of Section 5.2, which describes the package and gives extra information to the simple build infrastructure.
Now Angela can build her package by saying
./Setup.lhs configure ./Setup.lhs buildShe can even install it on her own machine by saying
./Setup.lhs installShe can build a HPS source distribution:
./Setup.lhs source-distThe full details are given in Section 5.3.
It is no coincidence that the interface is very similar to that for the setup script for an HPS package distribution (Section 4). In fact, Distribution.Simple.defaultMain conforms to the specification of Section 4.2, and when it builds a distribution, it includes ./Setup.lhs in the tarball, ready to be run by Bob the Builder. However, Distribution.Simple.defaultMain of course implements a richer interface than that required by Section 4.2, because it's intended to support Angela as well as Bob. The full specification is in Section 5.3.
When using the simple build infrastructure, the package description file pkg.desc contains not only the name of the package, its version and dependencies, but also a collection of information to explain to the simple build infrastructure how to build the package. This section gives the syntax.
For now, we just have a checklist of what must be there
exposed: Exposed modules
hidden: Hidden (or internal) modules
main modules: Which modules should be built into an executable
ghc-flags:,hugs-flags:,nhc-flags: Extra compiler flags for GHC, Hugs, Nhc98.
Why must we list hidden modules? These modules form part of the implementation of the package, but not its interface: a client of the package cannot import an internal module. They must nevertheless be listed explicitly for two reasons: (a) to allow the global program invariant to be checked (see Section 2.2) and (b) to enable a build system or programming environment to find the source files.
This section gives the command line interface supported by Distribution.Simple.main. It supports all the commands described in Section 4.2, and in addition the following:
The Haskell libraries that support the simple build infrastructure can, of course, also be re-used to make setup scripts that work quite differently. At one extreme is a setup script that immediately shells out into make, which does all the work.
To support this, HPS provides a trivial setup library Distribution.Make, which simply parses the command line arguments and shells out into make. Marcus uses the following Setup.lhs
#!runhugs > module Main where > import Distribution.Make (setup) > main = setupAll the package description information is assumed to be known to the makefile system, and so does not appear in the setup script. Thus,
setup configure --ghcinvokes
./configure --with-hc=ghcSimilarly setup build invokes make all And so on.
Marcus simply arranges that when his makefiles build a distribution, they include this simple setup script in the root of the distribution, where the Bob the Builder expects to find it.
Isaac isn't sure that we can provide much value here beside providing a standard command-line parser (which is pretty good at least). I think it might be good to offer a boilerplate Setup.lhs file for makefiles, but implementing it in a library is a bit overkill. Perhaps in the future, if the build system is delivered w/ fptools or something, we could provide an API to wrap that.
Simon says: fine -- but we should make it easy for Marcus Makefile. What do we offer?