Packages are collections of libraries, conveniently grouped together as a single entity. The package system is flexible: a package may consist of Haskell code, foreign language code (eg. C libraries), or a mixture of the two. A package is a good way to group together related Haskell modules, and is essential if you intend to make the modules into a Windows DLL (see below).
Because packages can contain both Haskell and C libraries, they are also a good way to provide convenient access to a Haskell layer over a C library.
GHC comes with several packages (see Haskell Libraries), and packages can be added/removed from an existing GHC installation, using the supplied ghc-pkg tool, described in Section 4.10.3.
To use a package, add the -package flag to the GHC command line:
This option brings into scope all the modules from package lib (they still have to be imported in your Haskell source, however). It also causes the relevant libraries to be linked when linking is being done.
Some packages depend on other packages, for example the text package makes use of some of the modules in the lang package. The package system takes care of all these dependencies, so that when you say -package text on the command line, you automatically get -package lang too.
It takes some special considerations to build a new package:
A package may contain several Haskell modules. A package may span many directories, or many packages may exist in a single directory. Packages may not be mutually recursive.
A package has a name (e.g. std)
The Haskell code in a package may be built into one or more Unix libraries (e.g. libHSfoo.a), or a single DLL on Windows (e.g. HSfoo.dll). The restriction to a single DLL on Windows is that the package system is used to tell the compiler when it should make an inter-DLL call rather than an intra-DLL call (inter-DLL calls require an extra indirection).
GHC does not maintain detailed cross-package dependency information. It does remember which modules in other packages the current module depends on, but not which things within those imported things.
To compile a module which is to be part of a new package, use the -package-name option:
This option is added to the command line when compiling a module that is destined to be part of package foo. If this flag is omitted then the default package Main is assumed.
Failure to use the -package-name option when compiling a package will result in disaster on Windows, but is relatively harmless on Unix at the moment (it will just cause a few extra dependencies in some interface files). However, bear in mind that we might add support for Unix shared libraries at some point in the future.
It is worth noting that on Windows, because each package is built as a DLL, and a reference to a DLL costs an extra indirection, intra-package references are cheaper than inter-package references. Of course, this applies to the Main package as well.
GHC uses a package configuration file, called packages.conf, which can be found in your GHC install directory. This file isn't intended to be edited directly, instead packages can be added or removed using GHC's package management tool, ghc-pkg.
This option displays the list of currently installed packages.
$ ghc-pkg --list-packages gmp, rts, std, lang, concurrent, data, net, posix, text, util |
Note that your GHC installation might have a slightly different set of packages installed.
The gmp and rts packages are always present, and represent the multi-precision integer and runtime system libraries respectively. The std package contains the Haskell prelude and standard libraries. The rest of the packages are optional libraries.
Reads a package specification (see below) on stdin, and adds it to the database of installed packages. The package specification must be a package that isn't already installed.
Removes the specified package from the installed configuration.
In both cases, the old package configuration file is saved in packages.conf.old in your GHC install directory, so in an emergency you can always copy this file into package.conf to restore the old settings.
A package specification looks like this:
Package { name = "mypkg", import_dirs = ["/usr/local/lib/imports/mypkg"], source_dirs = [], library_dirs = ["/usr/local/lib"], hs_libraries = ["HSmypkg" ], extra_libraries = ["HSmypkg_cbits"], include_dirs = [], c_includes = ["HsMyPkg.h"], package_deps = ["text", "data"], extra_ghc_opts = [], extra_cc_opts = [], extra_ld_opts = ["-lmy_clib"] } |
Components of a package specification may be specified in any order, and are:
The package's name, for use with the -package flag and as listed in the --list-packages list.
A list of directories containing interface files (.hi files) for this package.
A list of directories containing Haskell source files for this package. This field isn't used by GHC, but could potentially be used by an all-interpreted system like Hugs.
A list of directories containing libraries for this package.
A list of libraries containing Haskell code for this package, with the .a or .dll suffix omitted. On Unix, the lib prefix is also omitted.
A list of extra libraries for this package. The difference between hs_libraries and extra_libraries is that hs_libraries normally have several versions, to support profiling, parallel and other build options. The various versions are given different suffixes to distinguish them, for example the profiling version of the standard prelude library is named libHSstd_p.a, with the _p indicating that this is a profiling version. The suffix is added automatically by GHC for hs_libraries only, no suffix is added for libraries in extra_libraries.
Also, extra_libraries are placed on the linker command line after the hs_libraries for the same package. If your package has dependencies in the other direction (i.e. extra_libraries depends on hs_libraries), and the libraries are static, you might need to make two separate packages.
A list of directories containing C includes for this package (maybe the empty list).
A list of files to include for via-C compilations using this package. Typically this include file will contain function prototypes for any C functions used in the package, in case they end up being called as a result of Haskell functions from the package being inlined.
A list of packages which this package depends on.
Extra arguments to be added to the GHC command line when this package is being used.
Extra arguments to be added to the gcc command line when this package is being used (only for via-C compilations).
Extra arguments to be added to the gcc command line (for linking) when this package is being used.
For examples of more package specifications, take a look at the package.conf in your GHC installation.