[cvs pull, doc and examples ijones@syntaxpolice.org**20050210053112] { adddir ./doc adddir ./examples addfile ./doc/Cabal.xml addfile ./doc/Makefile addfile ./examples/Makefile addfile ./examples/hapax.hs hunk ./doc/Cabal.xml 1 + +Distribution.Simple'> + Distribution.Make'> + License'> + Extension'> + ]> + +
+ Common Architecture for Building Applications and Tools + User's Guide + + + The Cabal aims to simplify the + distribution of Haskell software. It does this by specifying a + number of interfaces between package authors, builders and users, + as well as providing a library implementing these interfaces. + + +
+ Packages + + A package is the unit of distribution + for the Cabal. Its purpose, when installed, is to make available + either or both of: + + + A library, exposing a number of Haskell modules. A library + may also contain hidden modules, which + are used internally but not available to clients. + Hugs doesn't support module hiding. + Just pretend they're not there, OK? + + + + + + One or more Haskell programs. + + + However having both a library and executables in a package + does not work very well, as the executables may not depend on + the library. + + Internally, the package may consist of much more than a bunch + of Haskell modules: it may also have C source code and header + files, documentation, test cases, auxiliary tools etc. + + A package is identified by a globally-unique + package name, an identifier containing + no spaces. Chaos will result if two distinct packages with the + same name are installed on the same system, but there is not + yet a mechanism for allocating these names. + A particular version of the package is distinguished by a + version number, consisting of a sequence + of one or more integers. These can be combined to form a single + text string called the package ID, using + a hyphen to separate the version from the name, and dots to + separate the version components, e.g. + HUnit-1.1. + + + Packages are not part of the Haskell language; + they simply populate the hierarchical space of module names. + It is still the case that all the modules of a program must have + distinct module names, regardless of the package they come from, + and whether they are exposed or hidden. + This also means that although some implementations (i.e. GHC) may + allow several versions of a package to be installed at the same + time, a program cannot use two packages, P and Q, which depend + on different versions of the same underlying package R. + +
+ +
+ Creating a package + Suppose you have a directory hierarchy containing the files + that make up your package. You will need to add two more files + to the root directory of the package: + + + package.cabal + + a text file containing a package description + (for details of the syntax of this file, see + ), and + + + + + Setup.hs or + Setup.lhs + + a Haskell script to perform various setup tasks (with + the interface described in ). + In most cases this will be trivial, calling on the Cabal + library to do most of the work. + + + + Once you have these, you can create a source bundle of this + directory for distribution. Building of the package is discussed in + . + + + A package containing a simple library + The HUnit package contains a file HUnit.cabal + containing: + +Name: HUnit +Version: 1.1 +License: BSD3 +Author: Dean Herington +Homepage: http://hunit.sourceforge.net/ +Category: Testing +Build-Depends: base +Description: + HUnit is a unit testing framework for Haskell, inspired by the + JUnit tool for Java, see: <http://www.junit.org>. +Exposed-modules: + Test.HUnit, Test.HUnit.Base, Test.HUnit.Lang, + Test.HUnit.Terminal, Test.HUnit.Text +Extensions: CPP + and the following Setup.hs: + +import Distribution.Simple +main = defaultMain + + + + A package containing executable programs + +Name: TestPackage +Version: 0.0 +License: BSD3 +Author: Angela Author +Build-Depends: HUnit + +Executable: program1 +Main-Is: Main.hs +Hs-Source-Dir: prog1 + +Executable: program2 +Main-Is: Main.hs +Hs-Source-Dir: prog2 +Hidden-Modules: Utils + with Setup.hs the same as above. + + + The trivial setup script used in these examples uses + the simple build infrastructure + provided by the Cabal library (see &Simple;). + The simplicity lies in its interface rather that its implementation. + It automatically handles preprocessing with standard preprocessors, + and builds packages for all the Haskell implementations (except + nhc98, for now). + + The simple build infrastructure can also handle packages + where building is governed by system-dependent parameters, + if you specify a little more (see ). + A few packages require more elaborate solutions + (see ). + +
+ Package descriptions + The package description file should have a name + ending in .cabal, and contain several + stanzas separated by blank lines. + Each stanza consists of a number of fields, with a syntax like + mail message headers. + + + case is not significant in field names + + + to continue a field value, indent the next line + + + to get a blank line in a field value, use an indented + . + + + Lines beginning with -- + are treated as comments and ignored. + + The first stanza describes the package + as a whole, as well as the library it contains (if any), using + the following fields: + + + name: identifier + + The unique name of the package, without the version number + (required). + + + + + version: string + + The package version number, usually consisting of + a sequence of natural numbers separated by dots + (required). + + + + + license: string + + The type of license under which this package is distributed. + License names are the constants of the &License; type. + + + + + license-file: filename + + The name of a file containing the precise license for + this package. + + + + + copyright: freeform text + + The name of the holder of the copyright on the package. + + + + + author: freeform text + + The original author of the package. + + + + + maintainer: email address + + The current maintainer of the package, if different + from the author. + + + + + stability: freeform text + + The stability level of the package, e.g. + alpha, experimental, + provisional, stable. + + + + + homepage: URL + + The package homepage. + + + + + package-url: URL + + The location of a source bundle for the package. + + + + + description: freeform text + + Description of the package. This may be several + paragraphs, and should be aimed at a Haskell programmer + who has never heard of your package before. + + + + + category: freeform text + + A classification category for future use by the package + catalogue Hackage. These categories + have not yet been specified, but the upper levels of the + module hierarchy make a good start. + + + + + tested-with: compiler list + + A list of compilers and versions against which the + package has been tested (or at least built). + + + + + build-depends: package list + + A list of packages, possibly annotated with versions, + needed to build this one, e.g. foo > 1.2, bar. + If no version constraint is specified, any version is assumed + to be acceptable. + + + + + exposed-modules: module list + + A list of modules added by this package (required if + this package contains a library). + + + + + This stanza may also contain build information fields relating + to the library (see ). +
+ Executables + Subsequent stanzas (if present) describe executable programs + contained in the package, using the following fields, as well as + build information fields (see ). + + + executable: string + + The name of the executable program (required). + + + + + main-is: filename + + The name of the source file containing the main module, + relative to the hs-sources directory + (required). + + + +
+ +
+ Build information + The following fields may be present in any stanza, and + give information for the building of the corresponding library + or executable. All are optional. + + + buildable: Boolean + + Is the component buildable? + (default: True.) + Like some of the other fields below, this field is + more useful with the slightly more elaborate form of + the simple build infrastructure described in + . + + + + + hidden-modules: module list + + A list of modules used by the component + but not exposed to users. For a library component, these + would be hidden modules of the library. For an executable, + these would be auxiliary modules to be linked with the + file named in the main-is field. + + + + + hs-source-dir: directory + + The name of root directory of the module + hierarchy, relative to the package root + (default: .). + + + + extensions: string list + + A list of Haskell extensions used by every module. + Extension names are the constructors of the &Extension; type. + These determine corresponding compiler options. + In particular, CPP specifies that + Haskell source files are to be preprocessed with a + C preprocessor. + + Extensions used only by one module may be specified + by placing a LANGUAGE pragma in the + source file affected, e.g.: + {-# LANGUAGE CPP, MultiParamTypeClasses #-} + + + + + options-ghc: string list + + Additional options for GHC. You can often achieve + the same effect using the extensions + field, which is preferred. + + Options required only by one module may be specified + by placing an OPTIONS_GHC pragma in the + source file affected. + + + + + options-hugs: string list + + Additional options for Hugs. You can often achieve + the same effect using the extensions + field, which is preferred. + + Options required only by one module may be specified + by placing an OPTIONS_HUGS pragma in the + source file affected. + + + + + options-nhc: string list + + Additional options for nhc98. You can often achieve + the same effect using the extensions + field, which is preferred. + + Options required only by one module may be specified + by placing an OPTIONS_NHC pragma in the + source file affected. + + + + + includes: string list + + A list of header files, typically + containing function prototypes for any foreign imports + used by the package. These will be included in any + compilations via C. + + + + + include-dirs: directory list + + A list of directories to search for + header files. + + + + + c-sources: filename list + + A list of C source files to be compiled + and linked with the Haskell files. + + If you use this field, you should also name the + C files in CFILES pragmas in the + Haskell source files that use them, e.g.: + {-# CFILES dir/file1.c dir/file2.c #-} + These are ignored by the compilers, but needed by Hugs. + + + + + extra-libs: string list + + A list of extra libraries to link with. + + + + + extra-lib-dirs: string list + + A list of directories to search for libraries. + + + + + cc-options: space separated list + + Command-line arguments to be passed to the C compiler. + Since the arguments are compiler-dependent, this field + is more useful with the setup described in + . + + + + + ld-options: space separated list + + Command-line arguments to be passed to the linker. + Since the arguments are compiler-dependent, this field + is more useful with the setup described in + . + + + + + frameworks: space separated list + + On Darwin/MacOS X, a list of + frameworks to link to. Take a look at Apple's developer + documentation to find out what frameworks actually are. + This entry is ignored on all other platforms. + + + +
+
+ +
+ System-dependent parameters + For this you need a slightly extended + Setup.hs: + +import Distribution.Simple +main = defaultMainWithHooks defaultUserHooks + This differs from defaultMain in two + ways: + + + If the package root directory contains a file called + configure, the configure step will + run that. This configure program + may be a script produced by the autoconf + system, or may be hand-written. In this way you can generate + system-dependent header files and the like. (Clearly this + won't work for Windows without MSYS or Cygwin: other ideas + are needed.) + + + + If the file + package.buildinfo + exists after the configuration step, subsequent steps will read + it to obtain additional build information. In particular, this + file may be produced by the configure + script mentioned above. + + + + The build information file should have the following + structure: + +buildinfo + +executable: name +buildinfo + +executable: name +buildinfo + +... + + Each buildinfo may include settings + of any of the fields listed in . + The first one (if present) relates to the library, while each + of the others relate to the named executable. (The names must + match the package description, but you don't have to have entries + for all of them.) + + The buildinfo's you + supply here will be merged with the ones given in the + .cabal file. In this way you can make some + of the above buildinfo fields vary + depending on the build environment. + + + Using autoconf + + (This example is for people familiar with the autoconf + tools.) + + In the X11 package, the file configure.ac + contains: + +AC_INIT([Haskell X11 package], [1.1], [libraries@haskell.org], [X11]) + +# Safety check: Ensure that we are in the correct source directory. +AC_CONFIG_SRCDIR([include/HsXlib.h]) + +# Header file to place defines in +AC_CONFIG_HEADERS([include/HsX11Config.h]) + +# Check for X11 include paths and libraries +AC_PATH_XTRA +AC_TRY_CPP([#include <X11/Xlib.h>],,[no_x=yes]) + +# Build the package if we found X11 stuff +if test "$no_x" = yes +then BUILD_PACKAGE_BOOL=False +else BUILD_PACKAGE_BOOL=True +fi +AC_SUBST([BUILD_PACKAGE_BOOL]) + +AC_CONFIG_FILES([X11.buildinfo]) +AC_OUTPUT + + Then the setup script will run the + configure script, which checks for the + presence of the X11 libraries and substitutes for variables + in the file X11.buildinfo.in: + +buildable: @BUILD_PACKAGE_BOOL@ +cc-options: @X_CFLAGS@ +ld-options: @X_LIBS@ + + This produces a file X11.buildinfo + supplying the parameters needed by later stages: + +buildable: True +cc-options: -I/usr/X11R6/include +ld-options: -L/usr/X11R6/lib + +
+ +
+ More complex packages + + For packages that don't fit the simple schemes described above, + you have a few options: + + + + Customizing the simple build infrastructure using + hooks. See &Simple; for details. + + + + You could delegate all the work to make, + though this is unlikely to be very portable. + + Cabal supports this with a trivial setup library &Make;, + which simply parses the command line arguments and invokes + make. Here Setup.hs + looks like + +import Distribution.Make +main = defaultMain + This assumes a configure script and + a Makefile with a default target that + builds the package, plus targets install, + register, unregister, + clean, dist. + (More detail needed.) + + + + Writing your own setup script conforming to the interface + of , possibly using the Cabal + library for part of the work. Good luck. + + +
+
+ +
+ Building and installing a package + After you've unpacked a Cabal package, you can build it + by moving into the root directory of the package and using the + Setup.hs or Setup.lhs + script there: + + runhaskell Setup.hs + command + option + + where runhaskell might be + runhugs, runghc or + runnhc. The command + argument selects a particular step in the build/install + process. + + + Building and installing a system package + +runhaskell Setup.hs configure --ghc +runhaskell Setup.hs build +runhaskell Setup.hs install + + The first line readies the system to build the tool using GHC; + for example, it checks that GHC exists on the system. The second + line performs the actual building, while the last both copies the + build results to some permanent place and registers the package + with GHC. + + + Building and installing a user package + +runhaskell Setup.hs configure --ghc --prefix=$HOME +runhaskell Setup.hs build +runhaskell Setup.hs install --user + In this case, since the package will be registered in the + user's package database, we also install it under the user's + home directory. + + + + Creating a binary package + When creating binary packages (e.g. for RedHat or + Debian) one needs to create a tarball that can be sent to + another system for unpacking in the root directory: + +runhaskell Setup.hs configure --ghc --prefix=/usr +runhaskell Setup.hs build +runhaskell Setup.hs copy --copy-prefix=/tmp/mypkg/usr +(cd /tmp/mypkg; tar cf - .) | gzip -9 >mypkg.tar.gz + After unpacking on the target system, the package must be + registered: + runhaskell Setup.lhs register + A similar procedure would be needed for creating Windows + installer packages. + + + The following options are understood by all commands: + + + , or + + + List the available options. + + + + + =n + or n + + Set the verbosity level (0-5). The normal level is 1; + a missing n defaults to 3. + + + + + The various commands and the additional options they support + are described below. In the simple build infrastructure, any + other options will be reported as errors, except in the case of + the configure command. + +
+ setup configure + Prepare to build the package. + Typically, this step checks that the target platform is capable + of building the package, and discovers platform-specific features + that are needed during the build. In addition to the general + options, this command recognizes the following + + + + =dir + + Specify the installation prefix + (default: /usr/local on Unix systems). + + + + + or + or + + + Specify which Haskell implementation to use to build + the package. At most one of these flags may be given. + If none is given, the implementation under which the setup + script was compiled or interpreted is used. + + + + + =path + or path + + Specify the path to a particular compiler. If given, + this must match the implementation selected above. The + default is to search for the selected compiler. + + + + + =path + + Specify the path to the package tool. + + + + + =path + + Specify the path to haddock. + + + + + =path + + Specify the path to happy. + + + + + =path + + Specify the path to alex. + + + + + =path + + Specify the path to hsc2hs. + + + + + =path + + Specify the path to cpphs. + + + + + In the simple build infrastructure, an additional option + recognized: + + + =dir or + dir + + Specify the directory into which the package will be + build (default: dist/build. + + + + + If a user-supplied configure script is + run (see ), it is passed the + option and any unrecognized options. + + In the simple build infrastructure, the values supplied via + these options are recorded in a private file for use by later + stages. + +
+ +
+ setup build + Perform any preprocessing or compilation needed to make this + package ready for installation. +
+ +
+ setup haddock + Build the interface documentation for a library using + haddock. +
+ +
+ setup install + Copy the files into the install locations and register the + package with the compiler, i.e. make the modules it contains + available to programs. This command takes the following + options: + + + + + + Register this package in the system-wide database. + (This is the default.) + + + + + + + Register this package in the user's local package + database. + + + +
+ +
+ setup copy + Copy the files without registering them. This command + is mainly of use to those creating binary packages. + This command takes the following option: + + + + =path + + Specify the directory under which to place + installed files. If this is not given, the + argument of the option to + configure is used. + + + +
+ +
+ setup register + Register this package with the compiler, i.e. make the + modules it contains available to programs. Note that the + install command incorporates this action. + The main use of this separate command is in the post-installation + step for a binary package. + + This command takes the following options: + + + + + + Register this package in the system-wide database. + (This is the default.) + + + + + + + Register this package in the user's local package + database. + + + +
+ +
+ setup unregister + Deregister this package with the compiler. +
+ +
+ setup clean + Remove any files created during the configure, build, or + register steps. +
+ +
+ setup sdist + This command is intended to create a system- and + compiler-independent source distribution, but it's not working + yet. + + The plan is to produce a file + package-version.tgz + which can be distributed to package builders. When unpacked, + the commands listed in this section will be available. +
+
+ +
+ Installed packages + + (steal from GHC User's Guide?) + +
+ Package management +
+ +
+ Installed package descriptions +
+
+ +
hunk ./doc/Makefile 1 +TOP = ../.. +include $(TOP)/mk/boilerplate.mk + +XML_DOC = Cabal +INSTALL_XML_DOC = $(XML_DOC) + +include $(TOP)/mk/target.mk hunk ./examples/Makefile 1 +# ----------------------------------------------------------------------------- + +TOP = ../.. +include $(TOP)/mk/boilerplate.mk + +# +# Disable 'make boot' +# +NO_BOOT_TARGET=YES + +WAYS= + +# ----------------------------------------------------------------------------- + +EXAMPLES := $(wildcard *.hs) +BINS := $(EXAMPLES:.hs=$(exeext)) +CLEAN_FILES += $(BINS) + +HC = $(GHC_INPLACE) +MKDEPENDHS = $(GHC_INPLACE) +SRC_HC_OPTS += -package Cabal + +all:: $(BINS) + +$(BINS): %$(exeext): %.hs + $(HC) -o $@ $(HC_OPTS) $(LD_OPTS) $< + +# ----------------------------------------------------------------------------- + +include $(TOP)/mk/target.mk hunk ./examples/hapax.hs 1 +-- Simple general-purpose Cabal setup script + +module Main (main) where + +import Distribution.Simple (defaultMainWithHooks, defaultUserHooks) + +main :: IO () +main = defaultMainWithHooks defaultUserHooks }