
Following long discussions on #haskell, here's some tricky cases we thought of with configurations. 1. build-depends: base configuration: debug build-depends: HUnit>=1.0 configuration: package(HUnit>=1.1) ghc-options: -DBlah The issue with this is what the "package(HUnit)" test means. Under one interpretation it just tests if that package is available (ie already installed), not if it's actually going to be used in this package. Under the other interpretation this can't be expressed since HUnit is not a top level dependency. Alternatively we could evaluate the configurations in order, in which case we've added HUnit>=1.0 to build depends before checking package(HUnit>=1.1). But making it order-dependent is ugly. 2. build-depends: base configuration: package(hdbc) build-depends: hdbc configuration: package(hsql) build-depends: hsql This is not ideal since it suggests that we will just pick up optional dependencies on packages if they are available with no control from the user as to whether they want those dependencies. This also means that the order in which you install packages can affect which features are enabled which makes the use of a dep resolver like cabal-install less intuitive as it becomes hard to predict how the packages will end up getting built. Incidentally this conflicts with distro package mangers like Gentoo's which specifically bans automatically picking up optional deps. It requires that all optional deps be specified before hand and be configurable by the user. This would also be difficult for binary package managers like debian as the debian package would just have to statically decide if hdbc or hsql or both will be used. Again, one option is to ban this on account of neither dep being mentioned in the top level build-depends. A better way to express this dependency might be: build-depends: base configuration: hdbc build-depends: hdbc configuration: hsql build-depends: hsql This means that we have flags "hdbc" and "hsql" and the user must specify at configure time --enable-hdbc or --disable-hdbc This way the optional dependency is not automatic and can be changed by the user. It's perfectly ok for there to be a default setting for the flag so long as the user can override it. This is much like Gentoo's USE flag system. 3. build-depends: base configuration: package(base<=1.0) build-depends: fps>=0.8 This one is ok. Is there a better way to do what we want without getting the bad cases? I am of the opinion that it makes little sense for conditional package tests to be of what packages are available in the environment rather than packages that have actually been chosen for this package. Remember that we can have multiple versions available so here's a case where 1. falls over. Here's case 1. again: 1. build-depends: base configuration: debug build-depends: HUnit>=1.0 configuration: package(HUnit>=1.1) ghc-options: -DBlah Suppose we have HUnit 1 and 2 installed. Suppose our package depends on another package which needs HUnit-1. With the debug flag enabled we depend on HUnit>=1.0. To pick a consistent HUnit version we must use 1.0 since we can't have two versions of the same package (even ghc's recent support for this doesn't help if HUnit gets used in the interface since the types would not match). So we pick HUnit-1.0. Now the configuration test "package(HUnit>=1.1)" is still true because there is version 2 available, even though we're not using it! This is not an intuitive semantics. If we say that package() tests must refer to packages we're going to actually build against on then this is fine and we get what the package author probably meant. So this suggests we should limit package() tests to packages that we depend on or might depend on. But for 1. we still have the issue of the order of evaluation of configuration stanzas being significant because they can add packages to build-depends which other stanzas may test. In gentoo such a dependency might be expressed as: DEPEND="debug? ( HUnit>=1.0 )" but then the action dependent on the version of HUnit that we picked would be done later. So there's a clear ordering. So one solution is to not allow build-depends in conditional stanzas but to specify conditional depends up front. build-depends: base, debug? ( HUnit>=1.0 ) configuration: debug ghc-options: -DDEBUG configuration: package(HUnit>=1.1) ghc-options: -DBlah or: build-depends: base > 1.0 || ( base <= 1.0 && fps >= 0.8 ), os(windows)? ( Win32 ), os(linux)? ( inotify ) configuration: package(fps) ghc-options: -DOLD_FPS configuration: package(base < 1.1) hs-src-dirs: compat So I guess the suggestion is that all deps are given up front and resolved. Then depending on what deps were chosen we can have other effects on the build like specifying extra src dirs or flags or whatever, but not specifying any more build-depends. So the order of checking configurations is independent again. Ok I've gone on long enough. Duncan