[Simon's additions to the overview doc simonpj@microsoft.com**20040427161713] { hunk ./doc/libraryInfrastructure.sgml 87 -
High-Level Overview +
What we are trying to achieve hunk ./doc/libraryInfrastructure.sgml 119 -
hunk ./doc/libraryInfrastructure.sgml 266 +
hunk ./doc/libraryInfrastructure.sgml 268 + + hunk ./doc/libraryInfrastructure.sgml 271 + +
The Haskell Library Infrastructure + +The Haskell Library Infrastructure (HLI) is a framework and supporting +code aimed at the above problem. It is Haskell-specific, but independent of +any particular Haskell implementation (Hugs, GHC, etc) or platform (Unix, Windows, etc). + +We use the term ``compiler'' to mean GHC, Hugs, nhc, hbc, etc. Even though +Hugs isn't really a compiler, the term is less clumsy than ``Haskell implementation''. + +
Packages + +A package is the unit of distribution. +A package has explicit dependencies on other packages. + +
+ +
What the compilers must implement + +The HLI requires that the Haskell implementations be somewhat package-aware. +This section documents those requirements + +
Registering a package + +Installing a package ultimately involves these steps: + + + Compiling the source files, by invoking the compiler. Even Hugs may require + some processing (e.g running cpp) + + + + Copying the compiled files into some place. Typically the compiler + places no pre-conditions on where "some place" is; instead one + usually follows the conventions of the host operating system. + + + + Registering the package: telling the compiler about the + existence of the package, and where its files are. + + +In step (c), the compiler records the package information in some +implementation-specific way; how it does so is not constrained by the HLI. +To register the package one invokes a compiler-specific program (ghc-pkg, +hugs-pkg etc), passing it a file describing the package. The format of this +file is independent of the compiler. + +It must be possible to register many versions of the same package. + +A complete program +can include more than one version of the same package. For example, the user might use +package A:2.1 and B:1.0; but B might use A:1.9. +
+ +
Module imports + + +Installing a package means that subsequent invocations of the compiler will use a module namespace +augmented by the newly-installed package. + + +By default, the module namespace is populated only by the latest version of a particular package. +This can be overridden using the -package flag. (Question: what does -package hunit:1.2 -package hunit:1.3 do? +Does the second override the first? Or are they both in scope? I think the former.) + + +An attempt to import a module that is defined by more than one installed package yields an ambiguous-import +error, rather like an attempt to use an identifier that is defined by more than one imported module. +(Comment: there ought be some way to resolve such ambiguities. Per-import qualification? -disable-package X? +-package Y specifies winner?) + +
+ +
The interface to <function>X-pkg</function> + +Each Haskell implementation X must provide an associated program X-pkg which +allows a user to make a new package known to the compiler, and to ask what packages it knows. + + X-pkg register hunit-config +or + X-pkg register < hunit-config. + + The syntax of the package install configuration, here hunit-config, is given below. + + + + X-pkg query "hunit" + + returns the version(s) of all hunit packages, latest version first. + + + +X-pkg query "hunit" 4.3.1 + + returns the package install configuration of hunit 4.3.1, in the same syntax + understood by X-pkg register, if it exists; or + the empty string otherwise. + + +
+ +
Syntax of package install configuration + +...include the list of ``externally visible modules''. +
+
+ + +
Installing a package: the end user viewpoint + +Joe User wants to install a new Haskell library, say HUnit, for GHC. How he does this depends on +how the library is packaged: + +Debian: + Joe says: + + apt-get install hunit-ghc + +And that's all. +Any packages that hunit-ghc depends on are automatically installed as well. + + +Linux RPM: + Joe says: +... +(Dependencies?) + + +Windows installer: + +Joe downloads hunit-ghc.msi, and double-clicks on it. +(Dependencies?) + + +Binary tar-ball: + +A binary tarball is a bunch of files, already precompiled and ready to install. +Joe downloads hunit-ghc.tar, unpacks the tarball in some temporary location, cd's to the root directory +and says + + ./setup.hs install + +or + + runhugs setup.hs install + +(or whatever is necessary to run the setup.hs Haskell script). +The script setup.hs does whatever is necessary to install the library. + + +(Dependencies?) + + +Source tar-ball: + +A source tarball contains the library sources, which may need to be +compiled before being installed. The same source tarball may well be installable for several +Haskell implementations. Joe downloads and unpacks the tarball hunit-src.tar, and then says + + ./setup.hs configure ghc + ./setup.hs build + ./setup.hs install + +The configuration step checks at least that (a) the package author indeed intends the package to be buildable +with GHC, and that a sufficiently up-to-date GHC is available, and (b) checks that the packages on which +hunit depends are already installed for GHC. After that the build and install steps know what +compiler they are using. + +Question: can you abbreviate to setup install ghc? + + + + +
<function>setup</function> targets + + +Here is a specification of the complete command-line interface for the setup.hs program +that must be delivered with a package: + + + setup configure + --with-compiler=ghc/hugs/nhc + --with-compiler-flags=-O + --prefix = xxx + -- what else? + + + +setup build + + + +setup install + + +It is expected that setup.hs will record the results of setup configure +in a file (and in a format) of its choosing. +
+
+ +
Building a package: the author's viewpoint + +Angela Author has written a bunch of Haskell modules that she wants to package as a library. +What does she have to do? +She must simply build a package that can be installed as described above: nothing else is prescribed. +However, the HLI provides support for library authors to make it easy to fulfil these requirements. + + +
The Makefile route + +If Angela is happy with make, then she can build the library entirely using make. + +To support this, HLI provides a trivial implementation of setup.hs, setup-make.hs, which +simply parses the command line arguments and shells out into make. Thus, + + setup configure --with-compiler=ghc + +invokes + + make configure HC=ghc + +Similarly +setup build +invokes +make build And so on. + +Angela simply arranges that when her makefiles build a distribution, they include this simple setup.hs in +the root of the distribution, where the Joe User expects to find it. +
+ +
The simple build infrastructure + + +In many cases, though, a Haskell package will consist of nothing more than a bunch of Haskell modules, +with perhaps the odd C file. In that case, the HLI provides a simple build infrastructure that +completely replaces make. (Think hmake.) The emphasis is on ``simple'': it deals with the 90\% case only. +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. Angela puts the following Hasell file setup.hs in the +root of her tree: + + module Main where + import Distribution.Setup.Simple + + pkgInfo :: PkgInfo + pkgInfo = .... + + main = setup pkgInfo + +Here PkgInfo is a data structure that describes the package: its name, version, dependencies, and so on (Section ...). +It is not the same as the package install configuration described in Section XXX; the latter describes a particular +installation (e.g. where the files are), while PkgInfo gives only installation-independent information. + +Now Angela can build her package by saying + + setup.hs build + +She can even install it on her ownn machine by saying + + setup.hs install + +She can build a source tarball: + + setup.hs source-tarball + +The full details are given in Section YYYY. + +It is no coincidence that the interface is very similar to that described for a package tarball (Section ZZZ). +In fact, Distribution.Setup.Simple.setup conforms to the specification of Section ZZZ, and when it builds +a tarball, it includes ./setup.hs in the tarball, ready to be run by Joe User. +However, Distribution.Setup.Simple.setup of course implements a richer interface than that required by +Section ZZZ, becuase it's intended to support Angela as well as Joe. +The full specification is in Section SSSS. + + +
<function>PkgInfo</function> + +...describe PkgInfo... + +Which compiler flags does she put in the compiler-flags part of PkgInfo, and which does she +pass to setup configure? Answer: the package should compile in a sensible way using only the +former. The latter are just for build-specific modification (e.g. make a debug build). +
+ +
<function>Distribution.Setup.Simpl.setup</function> + +Command line interface to the simple build infrastructure. +
+ +
+ +
RPMs and Debian packages + +How do we build these? +
+
+
+ + }