Cabal: Conditional code and dependencies

Brian Smith brianlsmith at gmail.com
Thu Jul 21 01:32:21 EDT 2005


It would be useful to have mechanisms in Cabal like these:

(1) Optional dependencies: "if package foo-1.0 is available, then my
program depends on it; otherwise, my program does not depend on it."
(see also #3 below). Special case: "my program would prefer package
foo-1.2, but if that is not available, I will take any version of
foo."

Use cases:

(a) A tool has an optional "XML export" feature that requires HaXml.
If HaXml is available, then the XML export feature will be built.
Otherwise, the tool will be built without it.

(b) A program requires some unix-specific code (package unix) or
windows-specific code (package win32) depending on what operating
system the program is built for.

(c) Cabal depends on HUnit if DEBUG is set, but it doesn't depend on
HUnit if DEBUG is not set. (The dependency isn't controlled by the
existence of a package, but by a configuration option.)

(c) Let's say I send in a patch that adds a "getAppBinaryDirectory"
function to System.Directory, and this patch makes it into version 1.1
of the base package. Then, Cabal 1.3 can say "If the base package
version is 1.1, then we want it because it defines
getAppBinaryDirectory, otherwise, we will just use base-1.0 and will
provide our own implementation of that function."

(2) "process this stanza if package foo-1.1 is available," etc. Use cases:

(a) A tool comes in a command line version and a GUI version. The
command-line version can be used independently of the existence of the
GUI version. The GUI version requires wxHaskell. So, we want to say
"build the GUI executable if wxHaskell is available, otherwise skip
it."

(b) A tool has a test suite that requires HUnit. If HUnit isn't
available, then the test suite should not be built.

(3) It would be useful if Cabal/GHC/Hugs/etc. #defined symbols for
installed packages. This would allow us to write:

module My.Program.Compat.Lib(foo1, foo2,foo3)
#if __PACKAGE_foo__ >= 110 -- Is package foo-1.1 or later available?
import Foo(foo1,foo2,foo3)
#else

foo1 = ....
foo2 = ....
foo3 = ...

#endif

Consider the following fragment from Cabal's
Distribution.Compat.Directory. The Cabal authors know that the version
of System.Directory that is in GHC before 6.02 includes the features
Cabal needs. However, other Haskell implementations have no such
version test:

#if !__GLASGOW_HASKELL__ || __GLASGOW_HASKELL__ > 602
import System.Directory
#else /* to end of file... */
...
#endif

Instead, we could have:

#if __PACKAGE_base__ >= 100
import System.Directory
#else /* to end of file... */
getAppUserDataDirectory = 
....
#endif

#if __PACKAGE_base__ < 110
getAppBinaryDirectory = ...
#endif

Regards,
Brian


More information about the Libraries mailing list