Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cabal install haskell-src-exts-1.10.1 indeterministically fails to regenerate the happy parser #2311

Open
hvr opened this issue Jan 2, 2015 · 11 comments

Comments

@hvr
Copy link
Member

hvr commented Jan 2, 2015

I noticed this because with GHC 7.8.4 cabal install haskell-src-exts-1.10.1 would sometimes succeed and sometimes fail with a compile failure in InternalParser.hs, depending on whether it was regenerated or not (GHC 7.8.4 requires parsers created by a recent enough happy)

I tracked this down to the way source-tarball are extracted, which seem to ignore the timestamps recored in the tarballs, and instead extracts the file with current system time.

So here's two example runs (I looked at the timestamps before cabal would decide whether to preprocess any files), which result in two cases in which the two files are in a different relative temporal relationship to each other:

  • case 1: .hs file older than .ly file (.hs file will be regenerated)

    -rw-rw-r-- 1 hvr hvr 505437 2015-01-02 19:59:46.556436392 +0100 haskell-src-exts-1.10.1-30225/haskell-src-exts-1.10.1/dist/dist-sandbox-4ac2267c/build/Language/Haskell/Exts/InternalParser.hs
    -rw-rw-r-- 1 hvr hvr  91522 2015-01-02 19:59:46.560436366 +0100 haskell-src-exts-1.10.1-30225/haskell-src-exts-1.10.1/src/Language/Haskell/Exts/InternalParser.ly
    
  • case 2: .hs exact same age as .ly file (.hs file is not regenerated -> compile failure)

    -rw-rw-r-- 1 hvr hvr 505437 2015-01-02 20:01:46.371660280 +0100 haskell-src-exts-1.10.1-31835/haskell-src-exts-1.10.1/dist/dist-sandbox-4ac2267c/build/Language/Haskell/Exts/InternalParser.hs
    -rw-rw-r-- 1 hvr hvr  91522 2015-01-02 20:01:46.371660280 +0100 haskell-src-exts-1.10.1-31835/haskell-src-exts-1.10.1/src/Language/Haskell/Exts/InternalParser.ly
    

Depending on whether case 1 or 2 occured (which depends on the operating system's clock accuracy, and interaction with process scheduling), the parser would be either regenerated or not.

There are a couple ways to workaround/fix this issue, here's just some ideas:

  1. A simple fix which would work in this case is to change the logic which decides whether to preprocess parsers to also regenerate in case of same-timestamps (this works as long as .ly is always extracted before the .hs -- does cabal sdist enforce this ordering in the tarball?)
  2. cabal install some-package could always consider a .ly file to be regenerated, because of GHC 7.8.x and later requiring recent enough happy to have generated the parser
  3. Extract files from source-tarball with recorded time-stamp. This would at least make the situation deterministic, although the parser would then probably never be regenerated, as the generated .hs file's timestamp would normally away be younger than the .ly file's.

/cc @feuerbach

@dcoutts
Copy link
Contributor

dcoutts commented Jan 6, 2015

Well done tracking it down to the tarball timestamps.

@dcoutts
Copy link
Contributor

dcoutts commented Jan 6, 2015

Using the timestamps when unpacking seems like a sensible thing to do.

The issue with ghc-7.8 and older happy should be dealt with separately as a special case.

hvr added a commit to hvr/cabal that referenced this issue Jan 14, 2015
This changes `moreRecentFile a b` to return true not only when `a`
is younger than `b`, but also when `a` is exactly the same age of `b`, as
that case is subject to race-conditions, and it's better to err on assuming
it needs to be regenerated.

This is an attempt to provide a pragmatic workaround for haskell#2311
@23Skidoo
Copy link
Member

Related: #130.

hvr added a commit to hvr/cabal that referenced this issue Jan 14, 2015
This adds `notLessRecentFile a b` to return true not only when `a`
is younger than `b`, but also when `a` is exactly the same age of `b`, as
that case is subject to race-conditions (if the system time granularity
is too low), and it's better to err on assuming it needs to be regenerated.

This is an attempt to provide a pragmatic workaround for haskell#2311
@ttuegel ttuegel modified the milestones: Cabal-1.24, Cabal-1.22 Apr 23, 2015
@NicolasT
Copy link

NicolasT commented Dec 1, 2015

I'm somewhat bitten by this as well: my package contains an in-tree autotooled library. A package sdist tarball contains correct timestamps: configure.ac and aclocal.m4 are 'older' than configure, config.h.in etc.
Due to Cabal not honouring timestamps during unpack, when running make after configure (done through a Custom Setup.hs and such), the autotools 'maintainer mode' rules kick in, after which on some systems (including Hackage) the build bails out because aclocal etc are missing (and they shouldn't be required either).

So, as long as cabal unpack doesn't honour tarball timestamps, I need to work-around this somehow (e.g. by explicitly passing --disable-maintainer-mode to configure, which isn't considered OK nowadays).

NicolasT added a commit to NicolasT/reedsolomon that referenced this issue Dec 2, 2015
After investigation of the build failures on Hackage, caused by autools
'maintainer mode' kicking in and required packages not being installed
on the build systems, it turns out `cabal unpack` doesn't honor
timestamps of files contained in `sdist` tarballs while unpacking. This
in turn causes some source files in `cbits` to appear newer than their
generated versions (e.g. `configure.ac` being newer than `configure`),
and the 'maintainer mode' rules being triggered, which we obviously
don't want to happen in release packages.

This patch changes `Setup.hs` to explicitly pass
`--disable-maintainer-mode` to `configure` in builds of packages whose
version number doesn't match the development version, 999.

This is a work-around for Cabal issue #2311.

See: haskell/cabal#2311
NicolasT added a commit to NicolasT/reedsolomon that referenced this issue Dec 2, 2015
Release 0.0.1.0 with changes to `Setup.hs` to pass
`--disable-maintainer-mode` to `configure` in release builds

After investigation of the build failures on Hackage, caused by autools
'maintainer mode' kicking in and required packages not being installed
on the build systems, it turns out `cabal unpack` doesn't honor
timestamps of files contained in `sdist` tarballs while unpacking. This
in turn causes some source files in `cbits` to appear newer than their
generated versions (e.g. `configure.ac` being newer than `configure`),
and the 'maintainer mode' rules being triggered, which we obviously
don't want to happen in release packages.

This patch changes `Setup.hs` to explicitly pass
`--disable-maintainer-mode` to `configure` in builds of packages whose
version number doesn't match the development version, 999.

This is a work-around for Cabal issue #2311.

See: haskell/cabal#2311
See: 4eeceb8

* tag 'reedsolomon-0.0.1.2':
  Release: Add generated autotools files
  Release: Set version number
NicolasT added a commit to NicolasT/reedsolomon that referenced this issue Dec 2, 2015
Release 0.0.1.1 with disabled maintainer mode during `cbits` build

After investigation of the build failures on Hackage, caused by autools
'maintainer mode' kicking in and required packages not being installed
on the build systems, it turns out `cabal unpack` doesn't honor
timestamps of files contained in `sdist` tarballs while unpacking. This
in turn causes some source files in `cbits` to appear newer than their
generated versions (e.g. `configure.ac` being newer than `configure`),
and the 'maintainer mode' rules being triggered, which we obviously
don't want to happen in release packages.

This patch changes `Setup.hs` to explicitly pass
`--disable-maintainer-mode` to `configure` in builds of packages whose
version number doesn't match the development version, 999.

This is a work-around for Cabal issue #2311.

See: haskell/cabal#2311
See: 4eeceb8

* tag 'reedsolomon-0.0.1.2':
  Release: Add generated autotools files
  Release: Set version number
@23Skidoo 23Skidoo modified the milestones: Cabal 1.24, Cabal 1.26 Feb 21, 2016
@hvr
Copy link
Member Author

hvr commented May 19, 2016

Fwiw, since directory-1.2.3 there's now a portable setModificationTime operation (see also haskell/directory#13). So cabal unpack could now try when compiled against directory >= 1.2.3 to set the mtime (and tolerate failure)?

@hvr
Copy link
Member Author

hvr commented Jun 19, 2016

After some more investigation, it turns out that some time ago haskell/tar@761bbc4 landed, so starting with tar-0.5.0.0 (in combination with directory >= 1.2.3), cabal sets modification times when unpacking source-tarballs.
So this should make cabal behave more deterministically.

As to whether this issue is fixed: depends on the versions of tar and directory that were used for building cabal :-/

@23Skidoo
Copy link
Member

Can we require tar >= 0.5 && directory >= 1.2.3 for 1.26?

@gbaz
Copy link
Collaborator

gbaz commented Feb 7, 2018

The tar dep is bumped, but the directory dep (for cabal install) is still 1.2.2. Can that be bumped?

@hvr
Copy link
Member Author

hvr commented Feb 7, 2018

Note that GHC 7.10.3 had directory-1.2.2 bundled, while GHC 8.0.1 had directory-1.2.6.2 bundled

@gbaz
Copy link
Collaborator

gbaz commented Feb 7, 2018

i forget the rules for ghc support windows..

@gbaz
Copy link
Collaborator

gbaz commented Feb 14, 2018

Hrm -- 7.10.3 was released 8th December 2015, so by the three year rule it needs to be supported until december 2018. That said -- it is allowable to bootstrap cabal-install (rather than cabal-the-library) with newer versions of libs than those shipped with ghc, so in theory it sounds like we could bump the version here if the bootstrap could be confirmed to work?

Or we could just wait a year, and then bump the dep with no work at all :-P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants