
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