issues with configurations

Simon Marlow simonmarhaskell at
Fri Aug 11 10:40:21 EDT 2006

Duncan Coutts wrote:
> On Fri, 2006-08-11 at 12:15 +0100, Simon Marlow wrote:

>>One goal (that I keep having to remind myself of) is that a .cabal file should 
>>be modifyable by an IDE such as Visual Haskell.  I can't see Visual Haskell 
>>being able to successfully modify that complicated build-depends expression.
> Is that really any different from the conditionals in the configuration
> tests?

Visual Haskell would ignore complicated configuration sections.  It can handle 
configuration sections that just test a single flag, because this fits in with 
the Visual Studio notion of "configurations".  It also needs to be able to grok 
and modify the build-depends field.  The idea would be that if you want to do 
anything more complicated, then you add a configuration section to the .cabal 
file by hand.

>>The whole thing is easier to understand IMO, and it's simple to implement too: 
>>no ordering, conditionals can be evalutated independently.
> Well they're only independent if you take the view that package()
> conditionals test what's available in the environment rather than what
> we're going to actually use.

Yes, that's the intended semantics (sorry for not saying that explicitly).  It's 
what makes simpler, but possibly too general.

>>I'm back to the two-argument package() conditional, because it's actually 
>>useful.  package(Hunit>=1, 1.1) is not the same as package(HUnit-1.1) or even 
>>package(HUnit>=1 && 1.1).  It says "the dependency HUnit>=1 resolves to version 
>>1.1", which is exactly what you wanted to know.  This is how you write 
>>conditionals that test the versions of packages you actually depend on, which is 
>>the criticism raised by Duncan at the beginning of this thread.  I believe my 
>>original syntax addressed this concern.
> Ok if we have package(Hunit>=1, 1.1) then do we not then have an
> ordering issue?

No, it's evaluated based on the environment only.  That's why the dependency is 
repeated from the build-depends field.

>>Now there are bad things that you can do with this syntax (auto-optional 
>>dependencies), and there are downright ridiculous things you can do with this 
>>syntax (test versions of packages you don't depend on), but I believe we could 
>>either make Cabal warn about those or disallow them altogether.  I don't mind which.
> I really worry that this will make many packages unpackagable because
> their semantics will not be translatable into sane distro packages. As I
> said, if I made a gentoo package that did auto-optional dependencies
> then the QA team would shoot me.

I imagine you could figure out for a given package description whether it had 
any auto-optional dependencies in it (it's not trivial, but not too hard I think).

> I think it's quite easy to make package tests be only internal, that is
> what deps have we resolved for the package, and not mix that up with
> what happens to be available in the environment. Then as a separate
> thing have some facility to make the default decisions about which
> configurations to use to depend on the environment, but in a clearly
> separated way so that users or packagers can override the defaults.

Ok - so is it a goal that you want to allow auto-optional dependencies but allow 
the packaging environment to turn them off?  If so, then I agree you need 
something like the scheme you suggest, I just want to be clear about why we need 
that (especially if auto-optional deps are considered evil).

> So let me suggest something with flags but without '?' syntax:
> flag: debug
> default: False
> configuration: flag(debug)
> build-depends: HUnit-1.1
> configuration: using(HUnit==1.1)
> ghc-options: -DHUNIT11
> flag: gui
> default: os(windows)
>       || (available(gtk>=0.9.10) && available(cairo>=0.9.10))
> configuration: flag(gui) && os(windows)
> build-depends: Win32>=1.1
> ghc-options: -DUSE_WIN32_GUI
> configuration: flag(gui) && !os(windows)
> build-depends: gtk>=0.9.10, cairo>=0.9.10, glib>=0.9.10
> ghc-options: -DUSE_GTK_GUI

with this you can still write silly tings - an available() condition for a 
package you don't care about, for example.

To summarise there are a couple of issues.  I'll use the abbreviations AOD for 
auto-optional dependencies and SC for silly conditionals (predicates on packages 
that aren't a dependency).

Ordering requirement on configurations:

   Option O1.  No ordering, requires 2-argument package() predicate.
               Allows AOD and SC, but we could (possibly) detect these.

   Option O2.  Ordering matters, we have using(P) predicates,
               doesn't allow AOD or SC.

Default settings for flags:

   Option D1.  All flags default to off.

   Option D2.  Defaults can be set based on the availability
               of packages.  Allows AOD and SC, but both can be
               disabled with a command-line switch.

If we can do without AOD, then we just choose between O1 and O2 - not a 
straightforward choice, but I went the O1 route because it's easier to implement 
and more declarative, on the other hand adding detection of AODs would mean more 

If we want AOD, then probably O2/D2 (the dcoutts proposal) is the sensible 
choice.  On the other hand, it means adding yet more stuff to Cabal...


More information about the cabal-devel mailing list