RE: Extending the dependency syntax

On 10 August 2005 06:56, Brian Smith wrote:
On 8/9/05, Simon Marlow
wrote: ------------------ build-depends: ghc? (ghc >= 6.4, [ghc64] | ghc >= 5.04, [ghc-old]) | hugs? [hugs], debug? (HUnit-1.0, [debug]) [release], gnome? ( libglade >= 2, gtksourceview >= 0.6, gconf >= 2, [gnome] ), mozilla? ( mozilla >= 1.4, [mozilla] ), doc? ( haddock >= 0.6 )
[gnome] extra-libraries: gnome extra-ghc-options: -DENABLE_GNOME ...
[debug] extra-ghc-options: -O0 -DDEBUG
[release] extra-ghc-options: -O2
As described, it seems like I would need to pass "--enable-hugs" or "--enable-ghc" explicitly, or else this program's build would fail. But, I don't think that is your intention; instead you are intending for Cabal to automatically enable these flags as appropriate, right? Perhaps there would be other automatic flags too, like "windows" and "unix"?
Actually I made a mistake in the above example, I meant to write build-depends: ghc? (ghc >= 6.4, [ghc64] | ghc >= 5.04, [ghc-old]) (hugs? [hugs]) but anyway, this syntax has caught several people out, me included, so we should pick something better (again). It seems that most people would be happier if x? (a) | b means b if x is false. I think we can fix it, though. How about this syntax: deps ::= choice | choice ',' deps choice ::= alt1 '|' ... '|' altN (n >= 1) | adep alt ::= adep '?' adep adep ::= pkg version-range | '(' deps ')' | --enable-flag | true The point is that now a disjunction is always of the form (x1?(a1) | ... | xn?(an)), and the meaning is that we take the leftmost branch for which x is true. It's a case statement. Also, to avoid some of the overloading you pointed out, I'm writing flags as --enable-flag. The example in this syntax: build-depends: --enable-ghc? ( ghc>=6.4 ? [ghc64] | ghc>=5.04 ? [ghc-old]) | --enable-hugs? [hugs] | true ? true, -- other compilers are allowed --enable-debug? (HUnit-1.0, [debug]) | true? [release] --enable-gnome? ( libglade >= 2, gtksourceview >= 0.6, gconf >= 2, [gnome] ), --enable-mozilla? ( mozilla >= 1.4, [mozilla] ), --enable-doc? ( haddock >= 0.6 ) I'm not wildly excited about "true ? true", but we could add special syntax for that if it turns out to be used often.
Can configurations contain their own "Build-depends", like this?:
[windows] Build-depends: Win32 extra-libraries: gnome
The problem I have with this is that it means you can only decide dependencies based on the settings of flags, rather than the other way around. We use both in the above example - [ghc64] is decided based on the availability of ghc versions, whereas [mozilla] is chosen based on a configuration flag. You had to hack it in your example:
I think it would be clearer to specify the configuration seperately, like this:
configuration: ghc >= 6.4 ? [ghc64] | ghc >= 5.04 ? [ghc-old]) | hugs? [hugs], debug enabled ? [debug] | [release], gnome enabled ? [gnome], mozilla enabled ? [mozilla], doc enabled ? [doc] -- the "global" Build-depends applies to everything Build-depends: base >= 1.0, haskell98 >= 1.0
So configuration contains dependencies like ghc >= 6.4. I think it's clearer to put all the dependencies in one place.
Finally, are you intending to allow multiple executable stanzas inside configurations?:
I've been avoiding this issue for now. I believe we need to completely redesign the way multiple executables are handled, and provide a more general framework for a package that contains multiple libraries & executables (essentially a wrapper for multiple packages with interdependencies). I know Isaac is thinking about this too. Let's deal with one issue at a time. Cheers, Simon

"Simon Marlow"
build-depends: --enable-ghc? ( ghc>=6.4 ? [ghc64] | ghc>=5.04 ? [ghc-old]) | --enable-hugs? [hugs] | true ? true, -- other compilers are allowed --enable-debug? (HUnit-1.0, [debug]) | true? [release] --enable-gnome? ( libglade >= 2, gtksourceview >= 0.6, gconf >= 2, [gnome] ), --enable-mozilla? ( mozilla >= 1.4, [mozilla] ), --enable-doc? ( haddock >= 0.6 )
What happens now with the issue that Duncan mentioned, where the built system picks up configuration information from the build / configure environment that's different from the user's environment? It could either pick up too much or too little. For "too little" we could use the --enable flags to override the detection mechanism, and maybe a --disable-all-detection mechanism similar to the -fhide-all-packages mechanism would be useful. One problem is that --enable-foo doesn't necessarily exist for optional dependencies. Another point: The dependency syntax you show mixes packages and pseudo-packages like GHC, alex, etc... I don't think we should use the same syntax / field for this, since in reality, they have separate namespaces. In fact you might be insane enough to want to talk about them separately: maybe you have the haxml library installed, but not the haxml toolchain... maybe you want the ghc executable, but not the ghc package... Stuff like GHC is auto-detected by looking in the PATH, which is dicier than using the package configuration database for a few reasons: 1) we have to pull tricks like: HC-pkg should be found at compiler-path++"-pkg". there may be other special cases out there, 2) we need to add a --with-tool= flag to configure for each tool, along with -extra-tool-opts 3) we can only handle tools we know about. We used to have a distinction between depends and build-depends, but we threw that away, I think because we weren't using the non-build-depends stuff at all... I note that having separate depends vs build-depends fields doesn't actually fix the above problems. BTW, are you suggesting that we change the meaning of depends and really adding a build-depends field? There are at least four kinds of simple dependencies, not taking into account configurations: 1) build-depending on packages - which is what depends: means now. This is always a build-time dependency. 2) build-depending on executables like GHC - that the simple build infrastructure knows about / needs. It would also be nice if we had a more sensible way of adding --with-foo= flags, extra-foo-opts, and configure-time detection for stuff in this category. 3) run-time depending on executables like gpg, gnome, etc. These are likely to be executables that Simple has never heard of before. 4) build-depending on stuff that the simple build infrastructure doesn't know about. This may not be very common, but folks not using Distribution.Simple may want to use this field to express dependencies too, so it would be nice if we could express build-time dependencies on non-package tools which we don't already know about. In reality, there are even more kinds :( The original request, I believe, was for better support of tool-depends mainly 2, but perhaps 3 and 4 are also important? 3 is a very common situation in Debian, and 4 is important for completeness for systems that don't want to use Distribution.Simple, and maybe for stuff like libglade? I have been thinking that Cabal should worry about 1 and 2 only, and let the OS package system worry about 3 and 4, but Duncan's requirements open the door to 3, and it's not going to be obvious to people that they can't talk about tools that Simple doesn't know about. In fact, it snuck into the above example. How the heck does Distribution.Simple know what version of Mozilla is installed? Maybe you didn't really mean that? But I do think that if we're overhauling the dependency syntax, we should think about all kinds of dependencies so we don't paint ourselves into a corner. 1 is the only kind that currently has a flexible infrastructure; 2 is done now, but can be sloppy sometimes; as I haven't always added --with-foo= flags when we need them and such. But how can we be flexible about 3 and 4? Are they important? Is $PATH searching good enough? Probably not; how do we discover versions? Maybe we should have a database similar to the hc-pkg database, but for tool dependencies, and we could include stuff like alex. But now I'm really drifting into the area of OS package management systems, and how do we get mozilla to register its version with the cabal package manager? Am I being too much of a perfectionist in trying to be complete here? Should we really just allow 1 and 2 and punt on the rest? Is it important to distinguish between 1 and 2? These are the questions I had in mind when I said earlier that cabal could become a generic packaging system if we kept going down this path. Also, I'm not sure we're really doing gentoo a favor by making the dependency syntax so complex. I think Duncan wanted to be able to automatically parse the cabal file and figure out the dependencies for alex and such, but now he's faced with: --enable-mozilla? ( mozilla >= 1.4, [mozilla] ), so he'll either have to figure all that out, or maybe he'll punt and suck out only the required dependencies.
Finally, are you intending to allow multiple executable stanzas inside configurations?:
I've been avoiding this issue for now. I believe we need to completely redesign the way multiple executables are handled, and provide a more general framework for a package that contains multiple libraries & executables (essentially a wrapper for multiple packages with interdependencies). I know Isaac is thinking about this too. Let's deal with one issue at a time.
Yes, that is still high on my list! Stayed tuned. peace, isaac

On 8/10/05, Simon Marlow
On 10 August 2005 06:56, Brian Smith wrote:
On 8/9/05, Simon Marlow
wrote: I'm not wildly excited about "true ? true", but we could add special syntax for that if it turns out to be used often.
Can configurations contain their own "Build-depends", like this?:
[windows] Build-depends: Win32 extra-libraries: gnome
The problem I have with this is that it means you can only decide dependencies based on the settings of flags, rather than the other way around. We use both in the above example - [ghc64] is decided based on the availability of ghc versions, whereas [mozilla] is chosen based on a configuration flag. You had to hack it in your example:
I think it would be clearer to specify the configuration seperately, like this:
configuration: ghc >= 6.4 ? [ghc64] | ghc >= 5.04 ? [ghc-old]) | hugs? [hugs], debug enabled ? [debug] | [release], gnome enabled ? [gnome], mozilla enabled ? [mozilla], doc enabled ? [doc] -- the "global" Build-depends applies to everything Build-depends: base >= 1.0, haskell98 >= 1.0
So configuration contains dependencies like ghc >= 6.4. I think it's clearer to put all the dependencies in one place.
Fair enough. But, you doesn't answer the original part of my question: can each configuration stanza contain its own "Build-depends" section too? Like I said, if a configuration stanza can contain _foreign library_ dependencies (e.g. Extra-libraries: shell32, libxml2) then it seems like we should be able to put _native library_ dependencies in the configuration stanzas too. Also, don't we need a way to version native library dependencies too? e.g. Extra-libraries: libxml2 >= 2.6.1. And then, do you want to allow conditional dependencies based on native library dependencies? And, if so, do you want them integrated into the Build-depends: field too? - Brian
participants (3)
-
Brian Smith
-
Isaac Jones
-
Simon Marlow