Extending the dependency syntax
Duncan Coutts
duncan.coutts at worcester.oxford.ac.uk
Thu Jul 28 17:36:00 EDT 2005
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#automatic_decisions
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
More information about the Libraries
mailing list