
Hello Cafe!
Cabal configurations are an often-requested new feature of Haskell's
packaging system Cabal. As part of my Google Summer of Code project
I implemented it with the feature set of the latest proposal[1]. I
would now like people to try it out and give some feedback if it
solves their problems, if there are bugs with the current
implementation, or if it breaks any install scripts.
So, if you have written a package and think your package could profit
from Cabal configurations, please adjust your package description and
try to build it on as many systems as possible and report any
problems (or successes).
Following are some instructions to get started.
Thanks,
/ Thomas
INSTALLING
[Note: The following build instructions are for a recent GHC. If you
have another Haskell compiler/interpreter you'll probably have to
adjust these steps a bit. Please report any problems you encounter.]
You should be able to get Cabal with configurations via:
$ darcs get --partial http://code.haskell.org/~nominolo/src/cabal
+configs/
Before installing you might want to hide the current cabal package
using (tt shouldn't be necessary, though) via
$ ghc-pkg hide Cabal
or
$ sudo ghc-pkg hide Cabal
depending on where Cabal is installed.
Installing the new Cabal should be as simple as:
$ cd cabal+configs
$ make install user=y PREF=~/sw
This will build Cabal with version 1.1.7, register it in the current
user's package database, and install it to the "sw" directory of the
current user home directory. Adjust the parameters to your needs.
To remove use:
$ make remove user=y PREF=~/sw
NEW FEATURES
The new constructs didn't integrate well with the conventional
syntax, so I changed it to a C-style block-style syntax. (This is
consistent with Haskell's use of { .. } in do-blocks; adding or
replacing this with an indentation-based approach is thinkable and
might actually integrate better with the rest of Cabal file syntax.
So yell if you want it--but no bike sheds please! ;)
The new syntax structures cabal files like this:
global properties
optional flags descriptions
Library {
library build properties and conditionals
}
Executable name {
executable build properties and conditionals
}
For an example, see below.
Inside the Library and executable sections you can now use
conditionals with the syntax:
body: cabal_stanza "\n" body
| "if" conditional "{" body "}" [ "else" "{" body
"}" ] body
| <nothing>
conditional: "os(" string ")"
| "arch(" string ")"
| "flag(" flagname ")"
| "True"
| "False"
| "!" conditional
| conditional "||" conditional
| conditional "&&" conditional
| "(" conditional ")"
Note that you cannot test for dependencies directly. The user either
specifies certain features she wants by switching flags on or off
during the configure step or Cabal picks a suitable flag assignment
for you, depending on which dependencies are available. Unless
specified otherwise, flag assignments default to True.
ATM, the only field specifying dependencies is "build-depends".
Options specified inside a conditional are (mostly) added to the
values specified outside. E.g.
GHC-Options: -Wall
if flag(debug) {
GHC-Options: -DDEBUG
}
when built with flag "debug" set to True will be built with
GHC-Options: -Wall -DDEBUG
For a more detailed description see[1]. The following example .cabal-
file should demonstrate the features (it is also available and
updated at[2]):
Name: Test1
Version: 0.0.1
Cabal-Version: >= 1.1.7
License: BSD3
-- License-File: LICENSE
Author: Thomas Schilling