Cabal hooks

Krasimir Angelov kr.angelov at
Thu Jan 13 04:23:58 EST 2005

On Wed, 12 Jan 2005 21:32:12 -0800, Isaac Jones <ijones at> wrote:
> Ross Paterson <ross at> writes:
> > On Tue, Jan 11, 2005 at 02:33:52PM +0200, Krasimir Angelov wrote:
> >> Isn't it simpler to change the hooks type to something like:
> >>
> >> PackageDescription -> IO PackageDescription
> >>
> >> where the argument is the original description and the result is the
> >> possible updated one? This avoids the need of merging and simplifies
> >> the library code.
> >
> > It replaces the need for merging with the need to check that they haven't
> > changed the fields they weren't supposed to.
> That's not too bad actually; definitely easier than merging, and
> conceptually simpler than defining either an
> AbstractPackageDescription (so we can actually tell when they've
> over-ridden a field) or a new buildinfo type.
> Though the advantage of the buildinfo type is that the inability to
> over-ride is enforced by the typechecker.
> > Other alternatives:
> > - have the prehooks return a type other than PackageDescription,
> >   containing only the fields they're allowed to override.  That means
> >   a different parser for buildinfo files.
> > - introduce a variant of writePackageDescription that only writes the
> >   fields they're allowed to override (or only writes non-empty fields).
> This second one is also quite easy and not a bad idea in general.

There is also an another solution which I proposed in our off-line
discussions with Ross. The hook can return [(String,BuildInfo)] where
the first element of the pair is the library/executable name to which
to the BuildInfo is related. The drawback here is that the field
exposedModules is in BuildInfo type but we would like to keep this
list constant over all platforms. My solution is to make a slight
refactoring. In the BuildInfo have three fields exposedModules,
hiddenModules and executableModules. The former two fields are used
only for libraries while the latter is used only for executables. It
is a little bit strange to have fields which are used only in some
cases. I propose to introduce a new type:

data Library = Library {
   exposedModules :: [String],
   buildInfo  :: BuildInfo
deriving (Show, Read, Eq)

The nice thing here is that now we have symmetry between executables
and libraries. The former is represented from Executable type and the
letter is represented from Library type. The executableModules and
hiddenModules fields can be merged. In some sense the main module of the
executable is like the exposed modules of the libraries but in both
cases there can exists other modules which are required in order to
build. These extra modules we can keep in hiddenModules field. This
avoids the need to have fields which are used only for executables or
only for libraries in the BuildInfo. After this refactoring BuildInfo
will contain only system dependent values which the hook can change.

The (PackageDescription -> IO PackageDescription) solution is simpler
but as you said the library must check whether the hook is changing
only the allowed hooks. I will be happy with either of the above
solutions and probably tomorrow I will have enough time to write some
code but we need to make a choice.


More information about the Libraries mailing list