Skip to content

Instantly share code, notes, and snippets.

@ezyang
Created December 27, 2017 00:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ezyang/817676c1bf0ce5f70583b7e05bbbd9b5 to your computer and use it in GitHub Desktop.
Save ezyang/817676c1bf0ce5f70583b7e05bbbd9b5 to your computer and use it in GitHub Desktop.

The Cabal file format

This document is a comprehensive reference manual for the Cabal file format.

Common formats

Version range

e ::= e "&&" e
    | e "||" e
    | "(" e ")"
    | "-any"
    | "-none"
    | "==" [0-9]+ ([0-9]+ )+ ".*"

Package description

Required fields for building

There are only four required fields for a Cabal package description to build with Cabal: name, version, cabal-version and build-type.

name: package-name (required)

The unique name of the package, without the version number. The name of the package must coincide with the name of the Cabal file; e.g., a package named p must have a file p.cabal. A valid package name consists of one or more non-empty alphanumeric components (with at least one alphabetic character) separated by hyphens. Numeric components are not permitted as they would be ambiguous with version numbers. Package names are case sensitive, but it is discouraged to have multiple packages that would case-insensitively compare equal, since such packages interact poorly with case-insensitive file systems like NTFS.

Some valid package names are reserved, because they would be ambiguous with special targets in the UI of package managers. Currently reserved package names are:

  • all
  • any
  • none
  • setup
  • lib
  • exe
  • test

Additionally, package names starting with z- are reserved, as these are used to backwards-compatibly encode internal libraries of packages which are registered to the package database.

Finally, names which are reserved file system names on Windows are prohibited. These are: COM, PRN, AUX, NUL, COMn (where n is from 1 to 9) and LPTn (where n is from 1 to 9).

Valid package names:

  • Cabal
  • cabal-install
  • gtk2

Invalid package names:

  • gtk-2-hs (numeric component is ambiguous)
  • foo--bar (double hyphen is not permitted)
  • -far- (leading/trailing hyphen is not permitted)
  • my_app (underscore is not permitted)

version: version-number (required)

The package version number, a sequence of natural numbers separated by dots. Conventionally, these version numbers follow the package versioning policy (TODO: link), where the increments to the first two natural numbers indicate major, backwards-compatibility breaking changes, an increment to the third number indicates a feature release, and an increment to the fourth number indicates a patch/bugfix-only release.

Version numbers are lexicographically ordered by version component; if one version number is a prefix of another, it always compares less than that number (i.e., 2.0 is less than 2.0.0; however, Hackage prohibits uploading multiple versions of a package which differ only in trailing zeros.) Cabal doesn't mandate a normal form for version numbers, so a package can choose to pad a version number with any number of zeros, but standard practice is to pad out a version number to four places.

One gotcha: for historical reasons, Cabal will parse version numbers with a trailing hyphen and then arbitrary string data, interpreting these as tags. However, these tags are ignored by Cabal proper, and should not be used in version numbers.

Valid version numbers:

  • 0.0.1.0
  • 2.0
  • 3

Invalid version numbers:

  • 2.0-beta (but it will parse!)
  • 3.0~2

cabal-version: >= x.y

The version of the Cabal specification that this package description uses. This serves two functions:

  1. It specifies what version of Cabal is necessary to support all of the features used in this package. If you use a Cabal feature that was introduced in x.y, you must specify a cabal-version of at least >= x.y
  2. It specifies a compatibility-level version, locking a package to the semantics produced by Cabal in x.y, even if future versions of Cabal change the meaning of certain constructs. This means increasing cabal-version can change the semantics of your package.

For historical reasons this is always expressed using >= version range syntax. Other forms version ranges are invalid.

For more details about minimum required versions and semantic changes, see cabal-version feature gating/behavior changes.

build-type: identifier

The type of build system used to build a package. The valid types are:

  • Simple, the basic build system which does not allow for any programmatic customization. Most packages can be built with just this.
  • Custom, which permits an arbitrary Setup.hs script to implement any rules you want. Conventionally, most custom Setup.hs scripts are implemented by using the Simple build system in conjunction with programmable hooks which can be used to customize the build.
  • Configure, a build system for packages which require running a configure script to detect system-dependent headers and libraries needed by a package.
  • Make, a build system which defers to a top-level Makefile in a directory. (This build system is rarely used, since it generally takes quite a lot of work to write a make-based build system for Haskell code)

In principle, the build-type field is redundant with the contents of the Setup.hs file, which must be provided even for non-Custom builds (a non-Custom build simply indicates that a Setup.hs is some standard template.) The motivation behind having a build-type is to make it easier for tools to identify that a package is using a particular build system and handle it specially. For example, cabal-install will generally not bother invoking a Setup.hs script if it knows that the build-type is Simple; instead, it will directly call into its linked copy of the Cabal library to perform the build.

For more information about each of these build systems, as well as template Setup.hs for non-Custom build types, see XXX.

Required fields for distribution

If you would like to upload your package to Hackage, there are a few more fields which must be specified (otherwise, Hackage will reject your package.) Failure to include these fields will cause cabal check to fail.

synopsis: freeform

A short, one-line description of the package. This description would be suitable as a byline of a title or a description in a table of packages. We recommend keeping this less than 80 characters.

This is your headline, so keep it short (one line) but as informative as possible. Save space by not including the package name or saying it's written in Haskell.

description: freeform

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.

For library packages, this field is used as prologue text by setup-haddock and thus may contain the same markup as Haddock documentation comments.

license: identifier

The type of the license under which this package is distributed. (XXX: Is this field normative, i.e., if you say BSD2, are you obligated to paste the exact BSD2 text in LICENSE?) Valid values for this field are: (XXX: Link these)

  • GPL
  • GPL-2
  • GPL-3
  • LGPL
  • LGPL-2
  • LGPL-3
  • AGPL
  • AGPL-3
  • BSD2
  • BSD3
  • MIT
  • ISC
  • MPL-2.0
  • Apache
  • Apache-2.0
  • PublicDomain
  • AllRightsReserved
  • OtherLicense

license-file: filename

license-files: filename list

The name of a file(s) containing the precise copyright and license for this package. The license file(s) will be installed with the package.

If you have multiple license files then use the license-files field instead of (or in addition to) the license-file field.

copyright: freeform

The content of a copyright notice, typically the name of the holder of the copyright on the package and the year(s) from which copyright is claimed. For example:

copyright: (c) 2006-2007 Joe Bloggs

maintainer: address

The current maintainer or maintainers of the package. This is an e-mail address to which users should send bug reports, feature requests and patches.

author: freeform

The original author of the package.

Other fields

stability: freeform

The stability level of the package, e.g. alpha, experimental, provisional, stable.

Although, in principle, this field can be used to designate the stability of a package, in practice, the stability of packages is rarely kept up to date (e.g., widely used, stable packages are still labeled "experimental.")

tested-with: compiler list

A list of compilers and versions against which the package has been tested (or at least built).

Build information

Library

Executable

Test suite

Benchmark

Foreign library

Conditional language

GHC-Cabal version decoder

General speaking, Cabal makes a major version release when GHC does. Here is a converter table to help you determine which version of Cabal corresponds to which version of GHC.

  • GHC 8.2 = Cabal 2.0 (2017)
  • GHC 8.0 = Cabal 1.24 (2016)
  • GHC 7.10 = Cabal 1.22 (2015)
  • GHC 7.8 = Cabal 1.18
  • GHC 7.6 = Cabal 1.16
  • GHC 7.4 = Cabal 1.14
  • GHC 7.2 = Cabal 1.12
  • GHC 7.0 = Cabal 1.10

cabal-version feature gating/behavior changes

Behavior changes:

>= 1.2

  • Prior to this version, it was permissible to place information about the library/executable in the top-level of the Cabal file, without making a stanza. In 1.2, use of stanzas became mandatory. If cabal-version is set to a version lower than 1.2, old-style, no-stanza parsing is available.

>= 1.8

  • Prior to this version, there was only one set of dependencies for the entire package; i.e., even if you declared a dependency in a test suite, it was visible to a library. In 1.8, this behavior changed, so that dependencies were accounted for each component separately (a test suite dependency would not be visible to the library, unless the library specified it as well.) If a package's cabal-version is not set to this version or later, it is not considered eligible for per-component builds in cabal new-build.

>= 2.0

  • Prior to this version, it was permissible for the module Main to be listed in other-modules, in violation of the fact that this field is only intended for non-Main modules. If cabal-version is set to 2.0 or greater, every module listed in other-modules will be passed to the compiler, along with the main module specified by main-is

Cabal uses cabal-version to gate certain features and/or modify the behavior of certain fields in Cabal files. Starting with 1.18, in this section we describe the exactly what features are gated in this way:

>= 1.18

  • C/C++/obj-C source file in main-is
  • extra-doc-files

>= 1.21

  • reexported-modules

>= 1.23

  • Internal/convenience libraries (TODO: double check tihs)
  • extra-framework-dirs
  • build-type Custom packages must specify custom-setup stanza with setup-depends field.

>= 1.25

  • scope
  • mixins
  • Use of autogen-modules mandated for autogenerated modules like Paths_*.hs

>= 2.0

  • Major bounded syntax in build-depensd, e.g., foo ^>= 1.2.3

Finally, 2.0 and later versions are treated specially for the purposes of dependency solving: any legacy custom setups which do not have explicit Cabal version bounds will be forced to select a version of the Cabal library earlier than 2.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment