On why 'available' is evil

Ian Lynagh igloo at earth.li
Wed Nov 1 22:50:53 EST 2006

On Wed, Nov 01, 2006 at 02:04:29AM +0000, Duncan Coutts wrote:
> In all this discussion on configurations I think I'm not getting over my
> main point about why we can't go for the 'easy' option of allowing
> package 'available' tests everywhere.

I don't think anyone is arguing that we should do.

> So, 1: it often doesn't mean what you want
> configuration: available(foo >= 2)
> cpp-options: -Denable_cool_feature
> There's no necessary relation between what packages are available in the
> environment and the one(s) that the package is going to be built
> against. So the above will fail if we actually build with foo-1 but
> foo-2 is available.
> What's worse is that it will likely work on the developers machine but
> fail on the users machine.

Am I right in thinking that your objection to removing "using" and

    build-depends: foo

    configuration: using (foo >= 2)
    cc-options: -DENABLE_NEW_WAY


    flag: new_way
    default: available(foo >= 2)

    configuration: new_way
    build-depends: foo >= 2
    cc-options: -DENABLE_NEW_WAY

    configuration: !new_way
    build-depends: foo < 2

is that people might incorrectly write something like

    flag: new_way
    default: available(foo >= 2)

    build-depends: foo

    configuration: new_way
    cc-options: -DENABLE_NEW_WAY

and not realise that it can break in some circumstances?

If so then I don't think we should worry about this. They could equally
well write

    build-depends: foo
    cc-options: -DENABLE_NEW_WAY

and not be aware that it will break for some people (e.g. those with foo
1) (OK, in this case they'd probably realise as they've made a #define
for it, but in the need-fps-if-base=1 they could easily not realise).

I don't think "using" is worth the pain just to protect people from
shooting themselves in certain feet. I especially don't think this
should be in the first implementation of configurations as:
* it'll make the implementation take longer to write, as things are
  much more complex with it
* it can be added in the future without breaking any cabal files that
  have been written, while it can't be removed without doing so

> 2: it allows auto-use deps
> An auto-use dep is one where we add an extra dependency on a package
> just because it's available.

Removing "using" doesn't enable auto-use deps.

> 3: it makes life hard for distros and cabal-get
> So cabal-get needs to figure out the order it's going to install things
> and forward-propagate the set of installed packages at that time to
> figure out if an extra dep on C will be needed or not.

"available" in flags has this problem:

    flag: foo
    default: available(bar)

    configuration: foo
    build-depends: baz

    configuration: !foo
    build-depends: quux

There will be different deps depending on whether bar will be installed
when this package is compiled. I don't see this as a problem as
cabal-get needs to work out what it's going to do before it does it
anyway, or it might compile a dozen packages before hitting a dependency
it can't satisfy and failing.

Whether cabal-get should try alternate orders if the first one doesn't
work is an interesting question, but not one I think we need to worry
about right now.

> 4: it makes the install order significant

Again, having "available" in flags already makes install order
significant, e.g.

    flag: foo
    default: available(bar)

    configuration: foo
    build-depends: baz

needs baz only if bar is installed first. If you specify all flags it
won't matter, of course.


More information about the cabal-devel mailing list