Hi All,
Before the 6.6 release we had a longish discussion on how to do
configurations and their semantics and implementation complexity etc.
I would like to re-propose the last scheme that I cam up with. I'll try
to make it a concrete proposal as well as giving some motivating
examples to give the intuition of the meaning.
Duncan, I have thought about this more and I have the following questions:
* How does the proposed configuration mechanism work with executables? Can executables be built conditionally? Does the chosen configuration apply to library and all executables in the package description?
* What happens when multiple configurations apply?:
Configuration: True
Build-depends: foo-1.0
Configuration: True
Build-depends: foo-1.0
I think that if more than one condition applies, then configuration should fail with an error.
* Are True and False really useful in cexp's? If a configuration is always selected (True) then the whole mechanism is not even needed, and if it is always False then it is never used. I think any combination of and's, or's, and not's with constants can be rewritten without the constants.
* You mentioned the case where a using(x) expression conflicts with a build-depends:
Configuration: using(foo = 1.0)
Build-depends: foo = 2.0
It seems to me that:
using(foo = x) == !(available foo > x),
using(foo > x) == (available foo > x),
using(foo < x) == !(available foo >= x),
because of Cabal's "use the latest available version" policy. If all usages of using(x) can be replaced with available(f(x)), then I think it would be better to just get rid of using(x) and allow available(x) in both fexp's and cexp's, for consistency. However, I know that you do not want to do that, because you don't want available(x) allowed in cexp's. As you noted previously in the thread, using(x) seems to cause a lot of complications--is it really necessary? I think your example of using(x) is easily rewritten to not require it:
flag: require-fps
default: !available(base >= 2)
configuration: require-fps
build-depends: fps >= 0.8
* Why not use [ os="linux" ] instead of [ os(linux) ]? Since we already have (=) for comparing package versions, it seems to be sensible to overload (=) to compare these flags as well.
* Your example used [ os(windows) ]. However, the value for System.Info.os is usually "mingw32" or "cygwin" (or similar) on Windows. I think that the os() and arch() values should be consistent with
System.Info whenever possible.
* Finally, I suggest that we create some package descriptions for complicated packages, to use as "use case" scenerios. In particular, I think that at least GHC, lhs2tex, wxHaskell, and network-alt would be cases to study. By having such use cases, you will have a clearer idea of exactly what is needed in practical usage. You can also use these cases to delineate the scope of Cabal's configuration mechanism. I have a Cabal files for GHC (stage2 only) that you can use if you think this is a good idea (actually, I can probably write the Cabal file for both stages of the GHC build, sans usages of features that Cabal doesn't have).
Please let me know if this feedback is helpful. I am thinking to embed Cabal in two different tools, which is why I am so interested in these little details.
Regards,
Brian