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 <[EMAIL PROTECTED]>
Maintainer: Thomas Schilling <[EMAIL PROTECTED]>
--Homepage: http://www.example.com/
Synopsis: Test package to test configurations
Description:
        See synopsis.
        .
        Really.
Category: Useless

Flag Debug {
  Description: Enable debug support
  Default:     False
}

Flag NoBuild {
  Description: Inhibit building this package.
  -- defaults to True
}

Library {
  Build-Depends:   base
  Exposed-Modules: Testing.Test1
  Extensions:      CPP

  -- flag names are case insensitive
  if flag(debuG) {
    CC-Options: "-DDEBUG"
    GHC-Options: -DDEBUG
  }

  if flag(NoBuild) {
    Build-Depends: nonexistentpackage
  }
}

Executable test1e {
  Main-is: T1.hs
  Other-modules: Testing.Test1

  if flag(debug) {
    CC-Options: "-DDEBUG"
    GHC-Options: -DDEBUG
  }
}

When configuring it with the usual command line, you now get an additional line, showing which flags were chosen:

$ ./Setup.lhs configure
configure: Reading installed packages...
Configuring Test1-0.0.1...
configure: Flags chosen: nobuild=False, debug=False
Setup.lhs: Warning: No license-file field.
configure: Dependency base-any: using base-2.1.1
  [...]

Note that, even though the default for the "nobuild" flag was True, the required dependencies weren't present, so it was forced to False. If you want to force flags to certain values you can do so by giving the --flags or -f flag to configure. Listing the (case-insensitive) name forces it to True, putting a "-" in front of the name forces it to False. For example:

$ ./Setup.lhs configure -fdebug
configure: Reading installed packages...
Configuring Test1-0.0.1...
configure: Flags chosen: nobuild=False, debug=True
Setup.lhs: Warning: No license-file field.
[...]

or

$ ./Setup.lhs configure --flags="-debug nobuild"
configure: Reading installed packages...
Configuring Test1-0.0.1...
Setup.lhs: At least the following dependencies are missing:
    nonexistentpackage -any
$

Note that if you want to change the configuration of a package, you have to ./Setup.lhs clean first, to make sure everything gets recompiled.

Good Luck!



[1] http://www.mail-archive.com/[EMAIL PROTECTED]/msg00282.html
[2] http://hackage.haskell.org/trac/hackage/wiki/CabalConfigurations

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to