issues with configurations
duncan.coutts at worc.ox.ac.uk
Fri Aug 11 11:41:02 EDT 2006
On Fri, 2006-08-11 at 15:40 +0100, Simon Marlow wrote:
> 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.
That's fair enough. Not having '?' deps is good for that I agree. I only
introduced that as a way of making configuration sections independent,
but there are probably nicer ways of doing that.
> >>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.
Right. That's the semantics that I objected to and tried to explain why
in another recent email.
> >>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.
I think I get that.
"the dependency HUnit>=1 resolves to version >1.1".
s/resolves to/would resolve to
That means that supposing I were to build-depend on HUnit>=1 then I
would get a version satisfying >1.1. So if that evaluates to true it's
not to say that I do depend on HUnit>=1 or that we are going to use
>1.1. Indeed we may actually end up depending on version 0.9 and this
test will still be true.
> > 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).
I don't mind too much if we have auto-optional dependencies but if we do
then we must have a way of controlling them manually. It's probably nice
to have. I expect most devs and users would like it. Most of the time
for end users it does the right thing.
> > 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.
Yes, that's true. I don't think it has any particularly bad consequences
though and developers are not likely to do it (unlike auto-optional deps
which devs will use if they're available).
> 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
Yes, I think that summarises it quite well.
> 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...
Aye, ho hum. I've not spotted any nice simple schemes that cope with the
proposed use cases.
More information about the cabal-devel