Cabal version constraint seems to be ignored.

Hi, I have two versions of Cabal, both are visible: $ ghc-pkg expose Cabal-1.16.0 $ ghc-pkg expose Cabal-1.18.1.2 I clone and build my package. Since I have GHC 7.6.3 it uses Cabal-1.16.0 (as specified in ghc-imported-from.cabal): $ git clone https://github.com/carlohamalainen/ghc-imported-from $ cd ghc-imported-from $ cabal install It looks like Cabal-1.16.0 was chosen, as expected: $ grep Cabal dist/build/autogen/cabal_macros.h /* DO NOT EDIT: This file is automatically generated by Cabal */ /* package Cabal-1.16.0 */ #define VERSION_Cabal "1.16.0" #define MIN_VERSION_Cabal(major1,major2,minor) (\ But my program doesn't run: $ ghc-imported-from src/Main.hs Main getArgs 11 11 --ghc-options --ghc-pkg-options GhcOptions [] GhcPkgOptions [] Language/Haskell/GhcImportedFrom.hs:132:54: Couldn't match expected type `Distribution.PackageDescription.BuildInfo' with actual type `Cabal-1.16.0:Distribution.PackageDescription.BuildInfo' In the fourth argument of `getGHCOptions', namely `binfo' In a stmt of a 'do' block: getGHCOptions [] c (fromJust $ cradleCabalDir c) binfo In the expression: do { c <- findCradle; pkgDesc <- GhcMonad.liftIO $ parseCabalFile $ fromJust $ cradleCabalFile c; let binfo = head $ cabalAllBuildInfo pkgDesc; getGHCOptions [] c (fromJust $ cradleCabalDir c) binfo } I'm surprised that the error didn't appear at compile time. I guess the first reference to Distribution.PackageDescription.BuildInfo is from Cabal-1.18.1.2? If I hide Cabal-1.18.1.2 then things work ok: $ ghc-pkg hide Cabal-1.18.1.2 $ cabal install $ ghc-imported-from .... (runs as expected) But I can't expect a user to know that they have to hide Cabal-1.18.1.2. Is this actually a GHC bug or have I stuffed up my ghc-imported-from.cabal file? Thanks, -- Carlo Hamalainen http://carlo-hamalainen.net

On Wed, Jan 22, 2014 at 4:43 AM, Carlo Hamalainen < carlo@carlo-hamalainen.net> wrote:
If I hide Cabal-1.18.1.2 then things work ok:
Does the behavior change if you build with a sandbox? (without hiding either Cabal via ghc-pkg?) If I had to hazard a guess, I'd say that the inability to specify dependencies for the build process are causing this problem, even though you're using build-type: simple; one cabal is used to set cabal-specific details in the cabal_macros.h file (which I'm assuming you're using somewhere in the source?) and another is picked based on the build-depends. That's just a guess, though... and if true, it's a wrinkle in the interactions between build-system dependencies and program build-time dependencies that I haven't run across before (even with Cabal-dev!). --Rogan
$ ghc-pkg hide Cabal-1.18.1.2 $ cabal install $ ghc-imported-from .... (runs as expected)
But I can't expect a user to know that they have to hide Cabal-1.18.1.2.
Is this actually a GHC bug or have I stuffed up my ghc-imported-from.cabal file?
Thanks,
-- Carlo Hamalainen http://carlo-hamalainen.net
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 22/01/14 18:07, Rogan Creswick wrote:
Does the behavior change if you build with a sandbox? (without hiding either Cabal via ghc-pkg?)
Yes, in particular: $ ghc-pkg expose Cabal-1.18.1.2 $ rm -fr .cabal-sandbox cabal.sandbox.config dist $ cabal sandbox init $ cabal install --dependencies-only $ cabal install $ .cabal-sandbox/bin/ghc-imported-from src/Main.hs Main getArgs 11 11 --ghc-options --ghc-pkg-options runs with no problems. I dug into this a bit more and I think it's a bug in my own code: the error that I quoted before was not the executable blowing up, instead it was runGhc exploding because I did not pass the right flags to the GHC API when I called "load LoadAllTargets". Stepping back, I can reproduce the error with plain ghci: $ ghci GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude> :l src/Main.hs [1 of 3] Compiling Language.Haskell.GhcImportedFrom.UtilsFromGhcMod ( Language/Haskell/GhcImportedFrom/UtilsFromGhcMod.hs, interpreted ) [2 of 3] Compiling Language.Haskell.GhcImportedFrom ( Language/Haskell/GhcImportedFrom.hs, interpreted ) Language/Haskell/GhcImportedFrom.hs:132:54: Couldn't match expected type `Distribution.PackageDescription.BuildInfo' with actual type `Cabal-1.16.0:Distribution.PackageDescription.BuildInfo' In the fourth argument of `getGHCOptions', namely `binfo' In a stmt of a 'do' block: getGHCOptions [] c (fromJust $ cradleCabalDir c) binfo In the expression: do { c <- findCradle; pkgDesc <- GhcMonad.liftIO $ parseCabalFile $ fromJust $ cradleCabalFile c; let binfo = head $ cabalAllBuildInfo pkgDesc; getGHCOptions [] c (fromJust $ cradleCabalDir c) binfo } Failed, modules loaded: Language.Haskell.GhcImportedFrom.UtilsFromGhcMod. whereas cabal repl works fine, because it parses the .cabal file and realises that it needs the earlier version of Cabal. Confirming this, if I use -package to specify the version of Cabal then it works fine: $ ghci -package Cabal-1.16.0 (all happy now) So I should look at how the latest Cabal (in particular "cabal repl") works out the right flags to pass to ghci, and incorporate that into my ghc-imported-from project. I see that the developer of ghc-mod has run into a similar issue recently: https://github.com/kazu-yamamoto/ghc-mod/issues/171
If I had to hazard a guess, I'd say that the inability to specify dependencies for the build process are causing this problem, even though you're using build-type: simple; one cabal is used to set cabal-specific details in the cabal_macros.h file (which I'm assuming you're using somewhere in the source?) and another is picked based on the build-depends.
That's just a guess, though... and if true, it's a wrinkle in the interactions between build-system dependencies and program build-time dependencies that I haven't run across before (even with Cabal-dev!).
Nope, it's a wrinkle in my understanding of Cabal/ghci/etc :) Thanks for the reply though, it helped me hunt down the problem. Cheers, -- Carlo Hamalainen http://carlo-hamalainen.net

On 14-01-22 07:43 AM, Carlo Hamalainen wrote:
I have two versions of Cabal, both are visible:
$ ghc-pkg expose Cabal-1.16.0 $ ghc-pkg expose Cabal-1.18.1.2
I clone and build my package. Since I have GHC 7.6.3 it uses Cabal-1.16.0 (as specified in ghc-imported-from.cabal):
But my program doesn't run:
But I can't expect a user to know that they have to hide Cabal-1.18.1.2.
It seems that you are using GHC API. Then your program starts a GHC session, which is not unlike an average ghci session, in particular: A. It will load and link libraries afresh during run time. This is independent of whatever your executable is linked with. B. And the default choice of libraries is, clearly: the newest unhidden version. Therefore, when your GHC session also has to work with compiled code built against older versions, there will be incompatibilities. What do you tell your users? I don't know. This is just one tip of a problem so widespread and entrenched, you cannot solve it alone. I cannot solve it alone, unless I am Imperator for Life. The problem is cultural and due to opinion leaders. The problem is: believing that multiple versions co-exist happily. Opinion leaders themselves do not run into troubles because they are cabal experts and they always tread cunningly through the jungle of multiple versions. That is what's wrong with opinion leaders. They are so expert that their ways are unsuitable for the rest of us. For the rest of us, cabal-install would be much better off defaulting to disallowing multiple versions in the first place. (It could provide overriding options to the experts.) In the particular case of the library Cabal 1.16 vs 1.18, Duncun Coutts explicitly said in IRC freenode #haskell that their co-existence is pretty harmless. Let your trouble be a lesson against that leader opinion. And let ghc-mod's trouble be another. P.S. cabal-install goes out of its way to dictate library versions to ghc. It begins with -hide-all-packages, then it recites, one by one, -package base-4.1.0.0, -package Cabal-1.16.0, -package text-0.11.3.1,... Are you going to bother to do the same?

On 26/01/14 20:16, Albert Y. C. Lai wrote:
It seems that you are using GHC API. Then your program starts a GHC session, which is not unlike an average ghci session, in particular:
A. It will load and link libraries afresh during run time. This is independent of whatever your executable is linked with.
B. And the default choice of libraries is, clearly: the newest unhidden version.
Therefore, when your GHC session also has to work with compiled code built against older versions, there will be incompatibilities.
Ah, I see.
What do you tell your users?
In my testing, using cabal sandboxes seems to work, but that's not really a full solution.
P.S. cabal-install goes out of its way to dictate library versions to ghc. It begins with -hide-all-packages, then it recites, one by one, -package base-4.1.0.0, -package Cabal-1.16.0, -package text-0.11.3.1,... Are you going to bother to do the same?
I did add some functionality like this recently: https://github.com/carlohamalainen/ghc-imported-from/commit/e1a212000a73372f... (around line 108) which is just using ghc-mod's API to do so. But I still run into the original problem that I had before, at least when not using a sandbox. I'm not sure what to do from here. -- Carlo Hamalainen http://carlo-hamalainen.net
participants (3)
-
Albert Y. C. Lai
-
Carlo Hamalainen
-
Rogan Creswick