Re: cabal-install-0.8 final testing

On Fri, 2009-12-18 at 19:44 -0800, Dave Bayer wrote:
Hi Duncan,
Installation was easy (I typed "cabal-install HTTP zlib cabal-install" ;-).
Thanks for testing it. I've uploaded it to hackage.
Overall, seems to work fine. I couldn't build darcs, but I couldn't do that by hand either; I used their binary installer. I don't think they build yet under GHC 6.12.1.
One oddity, I tried to use cabal install to install mmap, and it failed because the HUnit package was missing. I then installed HUnit without incident, went back and installed mmap without incident. No idea why this didn't work in one pass, but I have "sandbox" systems if you'd like me to see if I can reliably reproduce this.
Mm. This is a worse bug than I thought. It's not trivial to fix. I'll have to think about it. The problem is mmap uses: Executable mmaptest Main-is: tests/mmaptest.hs if flag(mmaptest) Buildable: True else Buildable: False Build-depends: base<5, bytestring, HUnit, directory Now the question is what does this mean exactly. The previous version of Cabal said essentially "well the executable needs HUnit thus the package needs HUnit". This despite the fact that we're not going to actually built this test executable! The current Cabal code takes a slightly different approach. It says at the end "oh this exe isn't buildable, so its deps do not contribute to the deps of the package". The problem is what it was doing before that. It sees the dependency on HUnit and checks that it can be satisfied. It's only at the end that it ends up discarding it. So if it was not actually available then it fails earlier. The reason it's then inconsistent between configuring a package and what the cabal install planner is doing is that the planner assumes all the packages on hackage are available (sort of) while when we get to actually configuring a package to install it, only the other installed packages are available. So that's why the same solver gives us different answers, because we're making different assumptions about the available packages. So the issue is we need to treat "Buildable: False" specially in the solver because if we end up picking a configuration with "Buildable: False" for a component then have to have not already required the dependencies for that component. Essentially we want to reinterpret it as something like: if flag(test) Buildable: True Build-depends: base<5, bytestring, HUnit, directory else Buildable: False So that the dependencies themselves are conditional on the component being buildable. Then the solver would do the right thing. In general I guess the transformation would look like: if A1 Buildable: False if A2 Buildable: False ... if B1 Build-depends: blah if B2 Build-depends: blah where A1,A2,... and B1,B2,... are arbitrary conditions (including none) then this becomes: if A1 Buildable: False if A2 Buildable: False ... if B1 && ! (A1 || A2 || ...) Build-depends: blah if B2 && ! (A1 || A2 || ...) Build-depends: blah ... I don't especially like this though. It makes the meaning of buildable rather magic. In the short term I may have to revert the change in behaviour so that these dependencies become unconditional again, even though they're not used. Sigh. Duncan

Duncan Coutts
if flag(test) Buildable: True Build-depends: base<5, bytestring, HUnit, directory else Buildable: False
Is this solution good for the time being? If so, I'll change it to make peace and happiness prevail among cabal users. Side question: mmaptest is meant to be devel/testing thing only that is not build during normal usage. Is there a better way to achieve such purpose? -- Gracjan

On Mon, 2009-12-21 at 11:34 +0000, Gracjan Polak wrote:
Duncan Coutts
writes: if flag(test) Buildable: True Build-depends: base<5, bytestring, HUnit, directory else Buildable: False
Is this solution good for the time being? If so, I'll change it to make peace and happiness prevail among cabal users.
I suggest you don't change anything until we decide what the semantics are supposed to be in this case.
Side question: mmaptest is meant to be devel/testing thing only that is not build during normal usage. Is there a better way to achieve such purpose?
Not something purpose designed at the moment. Duncan

On 20/12/2009 01:46, Duncan Coutts wrote:
On Fri, 2009-12-18 at 19:44 -0800, Dave Bayer wrote:
Hi Duncan,
Installation was easy (I typed "cabal-install HTTP zlib cabal-install" ;-).
Thanks for testing it. I've uploaded it to hackage.
Overall, seems to work fine. I couldn't build darcs, but I couldn't do that by hand either; I used their binary installer. I don't think they build yet under GHC 6.12.1.
One oddity, I tried to use cabal install to install mmap, and it failed because the HUnit package was missing. I then installed HUnit without incident, went back and installed mmap without incident. No idea why this didn't work in one pass, but I have "sandbox" systems if you'd like me to see if I can reliably reproduce this.
Mm. This is a worse bug than I thought. It's not trivial to fix. I'll have to think about it.
The problem is mmap uses:
Executable mmaptest Main-is: tests/mmaptest.hs if flag(mmaptest) Buildable: True else Buildable: False Build-depends: base<5, bytestring, HUnit, directory
Now the question is what does this mean exactly. The previous version of Cabal said essentially "well the executable needs HUnit thus the package needs HUnit". This despite the fact that we're not going to actually built this test executable!
The current Cabal code takes a slightly different approach. It says at the end "oh this exe isn't buildable, so its deps do not contribute to the deps of the package".
The problem is what it was doing before that. It sees the dependency on HUnit and checks that it can be satisfied. It's only at the end that it ends up discarding it. So if it was not actually available then it fails earlier.
I was following the description up until this paragraph (too many "it"s and "that"s, I'm not sure what they all refer to). Don't worry about it if it's hard to explain, but if you have time to elaborate a bit I'd be interested. Cheers, Simon

On Mon, 2009-12-21 at 12:44 +0000, Simon Marlow wrote:
The current Cabal code takes a slightly different approach. It says at the end "oh this exe isn't buildable, so its deps do not contribute to the deps of the package".
The problem is what it was doing before that. It sees the dependency on HUnit and checks that it can be satisfied. It's only at the end that it ends up discarding it. So if it was not actually available then it fails earlier.
I was following the description up until this paragraph (too many "it"s and "that"s, I'm not sure what they all refer to). Don't worry about it if it's hard to explain, but if you have time to elaborate a bit I'd be interested.
Sorry, I'll try again: There are essentially two stages to the resolution. The main one and a simple post-processing. The post-processing notes that some components are not buildable and so ignores the deps from those components. But that's not good enough because the first stage would already have failed if those dependencies of the non-buildable component were not available. So it's no good just doing it as a post-processing stage. We must properly express the fact that the dependencies are optional and related to whether or not the component is buildable. The solver currently does not know that "buildable" is special in any way. Indeed that it should be special is rather irksome. We had this field before we added conditionals. We would not have added "buildable" like this way after adding conditionals. Instead we should have added things with comprehensible semantics like "fail". Duncan
participants (3)
-
Duncan Coutts
-
Gracjan Polak
-
Simon Marlow