I noticed recently that with cabal-install-1.24.0.0, certain packages mysteriously fail to build in a sandbox when using a sufficiently old version of GHC. I'm having trouble coming up with a minimal reproducible test case, but I've at least been able to trigger this bug when installing statistics-0.13.3.0 (which depends on aeson-1.0.0.0) in a sandbox. Here is what I did:
$ cabal get statistics-0.13.3.0
Unpacking to statistics-0.13.3.0/
$ cd statistics-0.13.3.0/
$ cabal sandbox init
Writing a default package environment file to
/home/rgscott/Documents/Hacking/Haskell/statistics-0.13.3.0/cabal.sandbox.config
Creating a new sandbox at
/home/rgscott/Documents/Hacking/Haskell/statistics-0.13.3.0/.cabal-sandbox
$ cabal install --only-dependencies -w /opt/ghc/7.4.2/bin/ghc --dry-run
Resolving dependencies...
In order, the following would be installed (use -v for more details):
abstract-par-0.3.3
base-compat-0.9.1
binary-0.8.2.1 (latest: 0.8.4.1)
bytestring-builder-0.10.8.1.0
cereal-0.4.1.1 (latest: 0.5.3.0)
dlist-0.8.0.1
erf-2.0.0.0
fail-4.9.0.0
parallel-3.2.1.0
random-1.1
abstract-deque-0.3
text-1.2.2.1
hashable-1.2.4.0
nats-1.1.1
time-locale-compat-0.1.1.3
transformers-0.5.2.0
mtl-2.2.1
monad-par-extras-0.3.3
primitive-0.6.1.0
transformers-compat-0.5.1.4
tagged-0.8.5
unordered-containers-0.2.7.1
semigroups-0.18.2
vector-0.11.0.0
mwc-random-0.13.4.0
monad-par-0.3.4.8
scientific-0.3.4.9
attoparsec-0.13.0.2
aeson-1.0.0.0
vector-algorithms-0.7.0.1
vector-binary-instances-0.2.3.2
vector-th-unbox-0.2.1.6
math-functions-0.2.0.1
$ cabal install --only-dependencies -w /opt/ghc/7.4.2/bin/ghc
Resolving dependencies...
Notice: installing into a sandbox located at
/home/rgscott/Documents/Hacking/Haskell/statistics-0.13.3.0/.cabal-sandbox
<lots of build output elided>
Configuring aeson-1.0.0.0...
Building aeson-1.0.0.0...
Failed to install aeson-1.0.0.0
Build log ( /home/rgscott/Documents/Hacking/Haskell/statistics-0.13.3.0/.cabal-sandbox/logs/aeson-1.0.0.0.log ):
cabal: Entering directory '/tmp/cabal-tmp-5011/aeson-1.0.0.0'
Configuring aeson-1.0.0.0...
Building aeson-1.0.0.0...
Preprocessing library aeson-1.0.0.0...
[ 1 of 19] Compiling Data.Aeson.Types.Generic ( Data/Aeson/Types/Generic.hs, dist/dist-sandbox-23a31be8/build/Data/Aeson/Types/Generic.o )
[ 2 of 19] Compiling Data.Aeson.Internal.Functions ( Data/Aeson/Internal/Functions.hs, dist/dist-sandbox-23a31be8/build/Data/Aeson/Internal/Functions.o )
[ 3 of 19] Compiling Data.Aeson.Internal.Time ( Data/Aeson/Internal/Time.hs, dist/dist-sandbox-23a31be8/build/Data/Aeson/Internal/Time.o )
[ 4 of 19] Compiling Data.Aeson.Types.Internal ( Data/Aeson/Types/Internal.hs, dist/dist-sandbox-23a31be8/build/Data/Aeson/Types/Internal.o )
[ 5 of 19] Compiling Data.Aeson.Encoding.Builder ( Data/Aeson/Encoding/Builder.hs, dist/dist-sandbox-23a31be8/build/Data/Aeson/Encoding/Builder.o )
[ 6 of 19] Compiling Data.Aeson.Encoding.Internal ( Data/Aeson/Encoding/Internal.hs, dist/dist-sandbox-23a31be8/build/Data/Aeson/Encoding/Internal.o )
[ 7 of 19] Compiling Data.Aeson.Parser.Time ( Data/Aeson/Parser/Time.hs, dist/dist-sandbox-23a31be8/build/Data/Aeson/Parser/Time.o )
[ 8 of 19] Compiling Data.Aeson.Parser.Internal ( Data/Aeson/Parser/Internal.hs, dist/dist-sandbox-23a31be8/build/Data/Aeson/Parser/Internal.o )
[ 9 of 19] Compiling Data.Aeson.Parser ( Data/Aeson/Parser.hs, dist/dist-sandbox-23a31be8/build/Data/Aeson/Parser.o )
[10 of 19] Compiling Data.Aeson.Encoding ( Data/Aeson/Encoding.hs, dist/dist-sandbox-23a31be8/build/Data/Aeson/Encoding.o )
[11 of 19] Compiling Data.Aeson.Types.ToJSON ( Data/Aeson/Types/ToJSON.hs, dist/dist-sandbox-23a31be8/build/Data/Aeson/Types/ToJSON.o )
Data/Aeson/Types/ToJSON.hs:658:32:
Illegal operator `:*:' in type `a :*: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:668:49:
Illegal operator `:*:' in type `a :*: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:671:32:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:672:32:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:673:32:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:680:55:
Illegal operator `:.:' in type `f :.: g'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:720:36:
Illegal operator `:*:' in type `a :*: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:726:36:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:727:36:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:728:36:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:736:63:
Illegal operator `:.:' in type `f :.: g'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:829:42:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:869:40:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:908:56:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:923:40:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:946:40:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:1023:38:
Illegal operator `:*:' in type `a :*: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:1054:41:
Illegal operator `:*:' in type `a :*: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:1097:37:
Illegal operator `:*:' in type `a :*: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:1118:38:
Illegal operator `:*:' in type `a :*: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:1138:49:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:1161:49:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:1187:36:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
Data/Aeson/Types/ToJSON.hs:1213:36:
Illegal operator `:+:' in type `a :+: b'
Use -XTypeOperators to allow operators in types
cabal: Leaving directory '/tmp/cabal-tmp-5011/aeson-1.0.0.0'
cabal: Error: some packages failed to install:
aeson-1.0.0.0 failed during the building phase. The exception was:
ExitFailure 1
Another package that triggers this problem is text-show, although that takes longer to build than aeson does.
This problem does not seem to occur with GHC 7.6.3 or later.
Are you sure that this is a Cabal issue and not a problem with aeson code?
@23Skidoo, it's definitely not an aeson issue, since I can build statistics-0.13.3.0 fine with GHC 7.4.2 outside of a sandbox. (And if you don't believe me, you can see that TypeOperators is enabled at the top of Data.Aeson.Types.JSON.
This is quite mysterious!
I'm tentatively marking this as obsoleted by nix-local-build, but it's possible that the bug exists for new-build as well. Would be good to know.
What would be really helpful is the -v output, which would show us the command line invocation of GHC (and preferably, compared with an invocation that does successfully compile.) That might give some hints as to what's going on.
I tried to repro, but could not.
Sorry, I'm aware that this is an imprecise example. I'll try to boil it down to a simpler example sometime later today (and get the -v/new-build results as well).
OK, I managed to boil this down to a simpler testcase. I've moved the code into https://github.com/RyanGlScott/cabal3739. You should be able to reproduce the above error by following these steps:
$ git clone https://github.com/RyanGlScott/cabal3739
$ cd cabal3739/
$ /opt/cabal/1.24/bin/cabal sandbox init
$ /opt/cabal/1.24/bin/cabal install -v3 -w /opt/ghc/7.4.2/bin/ghc
(This assumes you're using hvr's Ubuntu PPA to install cabal-install-1.24 and ghc-7.4.2.)
The -v3 output of building cabal3739 is located here: https://gist.github.com/RyanGlScott/0aebd356a764913d8f467c72528b7b13
Wow, this is a weird one. Doing _any_ of the following will make /opt/cabal/1.24/bin/cabal install -v3 /opt/ghc/7.4.2/bin/ghc work when in the cabal3739 directory:
LANGUAGE pragmas in Data.Aeson.Types.ToJSON. Apparently, they're all needed to trigger this bug.cabal3739.cabal.cabal3739.cabal. Seriously. I tried adding a pretty dependency at the bottom, and it started working./opt/cabal/1.24/bin/cabal new-build -w /opt/ghc/7.4.2/bin/ghc works inside and outside of a sandbox.
@RyanGlScott This still does not reproduce for me, using ghc and cabal from @hvr's PPA. Are you sure this is not some corruption of your user package database? You can test this without blowing away your .cabal/.ghc directory by just setting HOME to somewhere else.
I set my $HOME to somewhere else and was still able to reproduce the error on two different 64-bit Linux machines.
Would it be possible to get access to one of the boxes that is failing? I've run out of Ubuntu-running machines (and without hvr's PPA, it's too difficult to get a working 7.4 install.)
Wow... I actually know exactly what this bug is about, as I stumbled over it myself a couple of weeks ago. @ezyang may remember I was banging my head debugging a really weird GHC 7.4 issue which turned out to be a bug in GHC 7.4's lexer with its handling of lexemes when placed near buffer-boundaries; this got fixed via ghc/ghc@c250f93bd38c7d8f6453dd79dd9951f9a02bf5a7
What made this bug so annoying it's highly dependent on how much whitespace is added by cpp (which changes depending on GCC version/Ubuntu version, _and_ also possibly pathnames ending up being inserted by cpp), and consequently whether the {- lexeme fell right on the buffer-boundary...
PS: this is easily workaroundable by a single-line patch to GHC 7.4.2's source-tree by increasing the initial buffer size to say 16k or so.
@hvr Thanks! So this is not a Cabal or sandbox issue after all.
@hvr to the rescue! Seriously, thanks for identifying the source of the issue鈥擨 felt like I was going insane for a while :)
That's kind of unfortunate that it's simply an obscure GHC 7.4 bug, but I suppose this gives me a reason to break out the new-build capabilities.
Most helpful comment
Wow... I actually know exactly what this bug is about, as I stumbled over it myself a couple of weeks ago. @ezyang may remember I was banging my head debugging a really weird GHC 7.4 issue which turned out to be a bug in GHC 7.4's lexer with its handling of lexemes when placed near buffer-boundaries; this got fixed via ghc/ghc@c250f93bd38c7d8f6453dd79dd9951f9a02bf5a7
What made this bug so annoying it's highly dependent on how much whitespace is added by
cpp(which changes depending on GCC version/Ubuntu version, _and_ also possibly pathnames ending up being inserted bycpp), and consequently whether the{-lexeme fell right on the buffer-boundary...PS: this is easily workaroundable by a single-line patch to GHC 7.4.2's source-tree by increasing the initial buffer size to say 16k or so.