
On Thu, 2005-07-28 at 10:13 +0100, Simon Marlow wrote:
Now, I suggest we expand the language of dependencies to include disjunction and optional stanzas. The syntax I have in mind is this:
deps ::= adep* dep-expr ::= deps '||' dep-expr adep ::= pkg version-range | '(' dep-expr ')' | '[' stanza ']'
The idea is that Cabal evaluates the dependencies trying disjunctions left-to-right, where optional stanzas [foo] are assumed to be satisfied. When a set of satisfying dependencies has been found, Cabal processes all the optional stanzas it contains.
While the sensible normal behaviour might be to just pick up as many dependencies as the environment supports, packaging systems like to know about all dependencies and control them. For example it is normal to build a package on one system and deploy it on another. If there are extra dependencies that are picked up (because they happen to be in the build environment) it may cause a failure on the target system because the dependency is not present. There is an article that explains this issue in more detail: http://www.onlamp.com/pub/a/onlamp/2005/03/31/packaging.html?page=2 See particularly the section on automatic decisions: http://www.onlamp.com/pub/a/onlamp/2005/03/31/packaging.html?page=2#automati... As an example consider Gtk2Hs which has a number of optional dependencies (libglade, GConf, Mozilla). If you do a normal build then it will automatically build all the optional bits for which the dependencies are satisfied. This is what casual users want. However for packagers we provide a --enable-packager-mode flag which turns off all automatic dependency decisions and so the packager must explicitly specify --enable-gconf --enable-libglade etc. In the Gentoo Gtk2Hs package we reflect these options so that a user may control optional dependencies, eg: USE="gnome -mozilla" emerge gtk2hs translates into enabling the dependencies on gnome and disabling the ones on mozilla. Now if a cabal package automatically picks up dependencies then we have a problem that we may build a package and have it pick up an unrecorded dependency on a package that is in the environment. So we would need to take a worst case approach and specify that all optional dependencies are in fact required. [ Why is this so: consider a package that has an optional dependency on a gui library. We build it and it picks up a dependency on the gui lib. Now if this dependency is not recorded then the package manager can make incorrect decisions (like allowing the gui lib to be uninstalled since it believes there are nothing using it). So the obvious solution is to make the gui lib a dependency of the package in question. But now we have defeated the purpose of of the convenient automatic dependency selection by making everything required. ] So the point is, the package manager must have complete visibility over the dependencies that the package picks up. So I would suggest that while the default should be to pick up dependences automatically that it be possible for a packaging tool to discover what the optional dependencies are and to force the decision rather than letting it be automatic (eg to allow not building the gui even though the gui lib is available on the build machine). example: ---------------- name: myprog version: 1.0 executable: mycliprog build-depends: base>=1.0 (|| gtk>=0.9.8 [gui]) (|| hscgi>=1.0 [cgi]) [gui] executable: myguiprog [cgi] executable: mycgiprog ----------------- Then when we configure we want to say something like: ./setup configure --without-features=gui --with-features=cgi So in summary, if optional things like this are to be introduced we have to be careful to design it in such a way that it is usable by packaging systems. Duncan