Configurations proposal

Brian Smith brianlsmith at gmail.com
Thu Oct 26 11:52:48 EDT 2006


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


It is important that builds be reproducible predictably, so I do not think
it is a good idea to introduce undefined behavior. I think this will be made
clearer when some real examples are created.

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


But, they are pretty close to the same. The feature causes multiple
difficulties. Do you have a real-world motivating example for it, that
cannot easily be replaced by adding a flag and using available(x)? I propose
that it be left out. Then the whole design becomes much simpler, doesn't it?
In particular, no backtracking or non-trivial constraint solving is needed.

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.


They can do this already with your configuration mechanism:

    Build-depends: foo >= 2.0, bar >= 3.0

    flag: minimum-versions
    Synopsis: Choose the minimum version number of all packages
    Description: This is useful to test that the minimum version
                          constraints in the package description are
correct.
    default: False

    configuration: flag(minimum-versions)
    Build-Depends: foo = 2.0, bar = 3.0

In the presence of flags and configurations, I do not think Cabal will be
able to provide a feature to do this automatically. For example:

If you want to extend Cabal to allow the user to specify a specific version
of a package on the command-line, again, I think this should be done with
flags. But, this requires that you allow non-boolean flags. Incidentally, if
os(), and arch() were non-boolean flags, you would not need special syntax
for them.

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


I agree with you, and that is partly why I am suggesting that using(x) is
not good--it exposes (most of) the functionality of available(x) in exactly
the context you do not want that functionality exposed.  But, mostly, I just
think it would be better to make the design simpler if possible.

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


I agree--I wish System.Info.os worked differently, actually. But, there are
apparently some people (not me) that use Haskell on Cygwin, and they need to
be able to detect it, because e.g. Posix and Readline are available on
Cygwin but not Mingw. Maybe os(x) should be either "mingw" or "cygwin"?

- Brian
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/cabal-devel/attachments/20061026/6ae823f9/attachment-0001.htm


More information about the cabal-devel mailing list