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

Building tests can cause unnecessary recompilation #2800

Open
crockeea opened this issue Nov 22, 2016 · 11 comments
Open

Building tests can cause unnecessary recompilation #2800

crockeea opened this issue Nov 22, 2016 · 11 comments

Comments

@crockeea
Copy link

The following steps cause the library portion of a project to be unnecessarily recompiled:

>stack build foo
>stack test foo

when the testsuite has a build-depend that isn't in the library.

For example, with this cabal file:

name:                foo
version:             0.1.1.0
stability:           experimental
build-type:          Simple
cabal-version:       >= 1.10

library
  default-language: Haskell2010
  exposed-modules:  Foo
  build-depends:    base
test-suite testfoo
  type:             exitcode-stdio-1.0
  default-language: Haskell2010
  main-is:          Main.hs
  build-depends:    base, data-default

I get the following:

> stack build foo
foo-0.1.1.0: configure
Configuring foo-0.1.1.0...
foo-0.1.1.0: build
Preprocessing library foo-0.1.1.0...
[1 of 1] Compiling Foo              ( Foo.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/Foo.o )
foo-0.1.1.0: copy/register
Installing library in ...
Registering foo-0.1.1.0...

> stack test foo
**foo-0.1.1.0: unregistering (dependencies changed)**
foo-0.1.1.0: configure (lib + test)
Configuring foo-0.1.1.0...
foo-0.1.1.0: build (lib + test)
Preprocessing library foo-0.1.1.0...
Preprocessing test suite 'testfoo' for foo-0.1.1.0...
[1 of 1] Compiling Main             ( Main.hs, .stack-work/dist/x86_64-linux/Cabal-.24.0.0/build/testfoo/testfoo-tmp/Main.o )
Linking .stack-work/dist/x86_64-linux/Cabal-1.24.0.0/build/testfoo/testfoo ...
foo-0.1.1.0: copy/register

I get foo-0.1.1.0: unregistering (missing dependencies: data-default) when the additional dependency has not yet been build, or foo-0.1.1.0: unregistering (dependencies changed) if the additional dependency has already been built. There's no need to unregister the library if it has already been built and I would like to additionally build the tests.

@pepeiborra
Copy link

+1
We have worked around this in our Cabal files by aggregating the dependencies of all the stanzas in the library stanza, but this defeats Weeder (and common sense).

@mgsloan
Copy link
Contributor

mgsloan commented Nov 3, 2017

Unfortunately, this is due to behavior in Cabal that we cannot work around. When tests are enabled, it combines their dependencies. Worth investigating whether it has changed in Cabal-2.0, and opening an upstream issue about it if one doesn't already exist.

@kindaro
Copy link

kindaro commented May 15, 2020

@mgsloan  I experience the problem as described in this issue, but I can build the same test suite with Cabal and no spurious rebuilds happen. Is your last comment here still actual? Can you give me some evidence that I can go over to the Cabal folks with?

See also #4977.

@wraithm
Copy link
Contributor

wraithm commented May 18, 2020

Yeah, honestly, this has been driving me insane for years.

@mgsloan
Copy link
Contributor

mgsloan commented May 18, 2020

@kindaro I don't know, I don't work on this stuff any more. I believe that newer Cabal versions treat components more homogenously and so this may indeed be resolveable.

There is some discussion of updating to Cabal's newer stuff in #2540

gasi added a commit to zoomhub/zoomhub that referenced this issue Nov 29, 2020
We do this by matching all build configurations and always include
building tests. Performing a regular build without tests and then running
the tests invalidates the previous build as test dependencies are added.

See:
- commercialhaskell/stack#4977 (comment)
- commercialhaskell/stack#2800 (comment)
gasi added a commit to zoomhub/zoomhub that referenced this issue Dec 18, 2020
We do this by matching all build configurations and always include
building tests. Performing a regular build without tests and then running
the tests invalidates the previous build as test dependencies are added.

See:
- commercialhaskell/stack#4977 (comment)
- commercialhaskell/stack#2800 (comment)
gasi added a commit to zoomhub/zoomhub that referenced this issue Sep 16, 2021
@wraithm
Copy link
Contributor

wraithm commented Apr 15, 2024

I think this one is fixed, no?

@wraithm
Copy link
Contributor

wraithm commented Apr 16, 2024

I think this one is fixed, no?

No, I confirmed that this issue is still there on master. Not fixed.

@wraithm
Copy link
Contributor

wraithm commented Apr 16, 2024

Unfortunately, this is due to behavior in Cabal that we cannot work around. When tests are enabled, it combines their dependencies. Worth investigating whether it has changed in Cabal-2.0, and opening an upstream issue about it if one doesn't already exist.

@mgsloan Do you know if this is still the case? Is this behavior fixed in Cabal?

@mpilgrem
Copy link
Member

This has come up recently on Matrix. I'll post more comprehensively here later. This is more a feature request than a bug: Stack is behaving as expected. Stack does not build a package's targeted components 'separately', it builds them 'all together' (if it can), so 'build lib against dependencies X, Y' and 'build lib (and test suite) against dependencies X, Y and Z' are different builds. There is a desire to change Stack so that it thinks of building in terms of 'components (of packages)' instead of 'packages (with components)', but that change is non-trivial. I think @theobat has been giving it the most thought in recent years, and he has an open issue here: #6356.

@wraithm
Copy link
Contributor

wraithm commented Apr 16, 2024

@mpilgrem Awesome. Thank you for the summary here. It'd be amazing to have this feature. Do you know if this package-oriented limitation is still in the Cabal library? Or is it purely a stack issue? Said another way, given the state of Cabal today, is it theoretically possible to build this component-oriented build in stack?

@mpilgrem
Copy link
Member

@wraithm, to approach building in terms of 'components (of packages)' requires Cabal >= 2.2, which is why Stack's support of Cabal < 2.2 was deprecated in Stack 2.15.1 and will be removed in a future version of Stack (it has already been removed from the master branch). As a consequence, future versions of Stack will not support GHC < 8.4 and, so, this decision was not taken lightly. It is discussed at: #6377.

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