Open andreasabel opened 5 months ago
Make sure Haskell files in explicit source directories take precedence over autogenerated Haskell files https://github.com/haskell/cabal/issues/8689 https://github.com/haskell/cabal/pull/8690
- Changed order or directories in GHC invocation so that source directories explicitly specified in cabal file will be considered before Cabal’s internal build directory.
https://github.com/haskell/cabal/blob/master/release-notes/WIP-cabal-install-3.12.x.0.md
(the fact that it's in release not yet-unreleased cabal-install rather than Cabal is a bug in itself)
These various orderings are such a mess: I think we've had several troubles like this one recently. I wonder if the ultimate solution is to check for duplicate entries in the set of paths and halt if such entries are found.
So this is an intended behavior change, not a regression. This means that one has to be more careful not to have outdated build-tool products left behind from manual invocations.
I wonder if the ultimate solution is to check for duplicate entries in the set of paths and halt if such entries are found.
Yes, it would not hurt if Cabal was more aware what it is doing. I have seen Stack emitting a warning in situations where there are duplicate sources for a module.
Also, since Cabal is a make-like tool, it could take timestamps into consideration. E.g. in my situation, Cabal-3.12 would "prefer" an existing Lexer.hs
from 2023 over regenerating it from the Lexer.x
of 2024. (Of course, it does not actively prefer something if it simply gives include paths to GHC in a certain order.)
Timestamps of course get lost during sdist
, which creates this archive:
fred-0/Setup.hs
fred-0/fred.cabal
fred-0/src/
fred-0/src/Fred.hs
fred-0/src/Fred.y
Technically, the present issue is a change in Cabal-3.12
already and not just in cabal-install-3.12
, so it would deserve some mentioning also in the Cabal-3.12 release notes at https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.12.0.0.md , with examples explaining the new behavior. (But maybe one was not aware of extent of the change introduced by #8690.)
FWIW, hadrian
has this behaviour (prefers .hs files over .x) files, which is by design so that we can ship source distributions which don't need alex
/happy
to build.
It looks like the trick is to know which module would be picked up and which the user actually intended to pick up.
It does seem cabal has facility to state that modules should be only generated from a non-.hs
file via autogen-modules
but OTOH it needs to do something (reasonable?) when that field is not used in the cabal file and module is just listed in a list of modules in which case cabal will magically do the right thing. Perhaps all the confusion is due to too much magic.
Maybe cabal should be sticter and plainly refuse to do anything if the user asked for, say, module Foo
not listed under autogen-modules
but cabal can only find Foo.x
. And vice versa don't proceed if module is listed under autogen-modules
but a .hs
file was found.
@sergv wrote:
Maybe cabal should be sticter and plainly refuse to do anything if the user asked for, say, module
Foo
not listed underautogen-modules
but cabal can only findFoo.x
.
Yes, the problem is that in ambiguous situations, cabal
autonomously decides what to do, and different versions decide differently.
If one goes to a more stricter handling, one has to find a way not to break the thousands of of packages on Hackage (out of which at least 3000 are worth keeping, those that are tracked by Stackage).
One could bind the new behavior to the cabal-version
. (However, folks are in general unwilling to bump the cabal-version because of fearing to lose buildability with older versions of cabal / older LTSs.)
@andreasabel It seems there's no good way other than introduce stricter handling with newest cabal-version
, breaking lots of existing packages is not an option.
I guess people don't bump cabal version because it's not clear what it would improve other than reduce buildability. Personally I lean to newer cabal versions but even then I'm not sure which one is the newest and why it's better than 3.0
. Potentially, and with suitable advertisement, ala "this release has less magic and brings more control to the programmer" people could start trying out e.g. cabal-version: 3.14
or something.
A full reproducer with analysis is at https://github.com/andreasabel/bug-cabal-3.12-setup .
I noticed this issue when using ghc-9.10.1 for the first time to build Agda using
cabal v1-install
. The Agda parser was malfunctioning. Turned out I had a staleLexer.hs
next to myLexer.x
, and this would be used when building with ghc-9.10 but not when building with ghc-9.8. After some hours I traced the problem down to the version of theCabal
library shipped with these GHCs.In short
Cabal-3.12 passes the include directories to GHC in a different order than Cabal-3.10. Cabal-3.10 puts
dist/build
before thehs-source-dirs
whereas Cabal-3.12 does it the other way round. This leads GHC to pick up a different.hs
file:Cabal-3.10
the one generated by the build-tool.Cabal-3.12
the one sitting in the source tree.The problem is reproduced in a GitHub workflow run here: https://github.com/andreasabel/bug-cabal-3.12-setup/actions/runs/9291884301 . Passes with GHC 9.8, fails with GHC 9.10, independent of the version of
cabal-install
.Full description
It follows a longer description copied from https://github.com/andreasabel/bug-cabal-3.12-setup/blob/61cdad9444a3b13e2b833e1dde36019c4a31f782/README.md
Cabal-3.12 passes include dirs in wrong order to GHC
Conditions:
cabal v1-install
Setup.hs
), so thatCabal-3.12
is usedlibrary
(not just anexecutable
)happy
here to shadow a.hs
file by a.y
filehs-source-dirs
is not.
but e.g.src
Files:
fred.cabal
withbuild-type: Custom
library
withhs-source-dirs: src
(in particular not.
)Setup.hs
(standard)src/Fred.y
: processed byhappy
src/Fred.hs
: stale code that should be shadowed byFred.y
alwaysIn this setting
cabal v1-install
malfunctions ifghc
isghc-9.10.1
. (Works with older GHCs.) It picks upsrc/Fred.hs
instead ofdist/build/Fred.hs
that is created byhappy
fromsrc/Fred.y
.Looking at the verbose output
cabal v1-install -v3
, we notice a difference in the call toghc
when the GHC is 9.10.1.GHC 9.10 / Cabal-3.12
GHC 9.8 / Cabal-3.10
When building with GHC 9.8, library
Cabal-3.10
is used which places the pathdist/build
with the generated files correctly before the path.
of the source files; but with GHC 9.10, libraryCabal-3.12
is used which does it the other way.Full calls:
GHC 9.10 / Cabal-3.12
GHC 9.8 / Cabal-3.10