Configurations proposal

Duncan Coutts duncan.coutts at worc.ox.ac.uk
Thu Oct 26 09:10:01 EDT 2006


On Wed, 2006-10-25 at 22:19 -0500, Brian Smith wrote:
> On 10/24/06, Duncan Coutts <duncan.coutts at worc.ox.ac.uk> wrote:
>         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?

that's not quite clear yet. I invite suggestions. It might be useful to
have executable stanzas inside conditional stanzas, and it may be useful
to have conditional stanzas inside executable stanzas.

> * 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. 

I think it's important that mutliple configurations can apply at once.
So then the question is how do we interpret additions to fields, eg do
we interpret them as sets or multi-sets. I think we'll have to say that
the order in which the flags are added is undefined (eg for things like
cc-options).

> * 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're right that they're not directly useful but they can easily be
expresses using and or & not. We do need convenient True and False in
fexps so for consistency I would allow them in cexps, as they do no
harm.

> * 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.

They're not the same. If the latest versions of each package do not
satisfy the constraints then Cabal may have to pick different versions
and then the above do not hold.

Additionally, there's no reason why Cabal should not be extended to
allow users to build against older versions of libs they have installed,
eg for testing purposes or because they know only the older version is
available on some site where they intend to deploy.

>  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: 

But even if using is equal to some available expression in normal
circumstances, there's still a reason for using rather than available,
which is that using is less expressive. It doesn't allow packages to
automatically pick up dependencies merely because they're available in
the environment. This is one of the main points of the design. Anything
like that has to go via a flag, which is then controllable by the user
or package manager.

> * 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. 

Yeah, I don't mind. It was just for consistency with the other tests.
Convince everyone else.

> * 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.

You're probably right, though that in it self needs resolving since
people do need reliable tests for being on windows.
(os(mingw32) || os(mingw64) || os (cygwin)) starts to get a little
unwieldy.

> * 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). 

Very good idea.

> 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.

Lots of interesting points. Good stuff.

Duncan




More information about the cabal-devel mailing list