Home > Net >  GHCI needlessly recompiles sub-package
GHCI needlessly recompiles sub-package

Time:08-06

I have a project (let's call it parent) that has a sub-package (child). Using HLS from emacs, whenever I change a file in the parent that imports part of the child package, and try to load it, GHCI will recompile the whole sub-package again every time. The sub-package has lots of TH code in it and takes a long time to compile, which really messes with your workflow when you just want to check if something works. Any ideas?

I'm using

  • stack 2.7.5 with resolver lts-18.28
  • cabal 3.6.2.0
  • GHC 8.10.7
  • HLS 1.7.0.0

My stack.yaml in the parent package:

resolver: lts-18.28

packages:
- .
- sub-package

extra-deps:
- ... (omitted)

allow-newer: true

EDIT: Minimal example: git repo

file details:

parent stack.yaml

resolver: lts-18.28

packages:
- .
- child

child stack.yaml

resolver: lts-18.28

packages:
- .

parent main src/Parent.hs:

module Parent where

import Child

someFunc :: IO ()
someFunc = childFunc

child main file child/src/Child.hs:

module Child where

childFunc :: IO ()
childFunc = putStrLn "someFunc"

CodePudding user response:

I'm not sure how this handshakes with HLS, but when you run stack ghci, by default it loads modules from all packages in the project into GHCi, all in an interpreted form, which means recompiling Child.hs every time GHCi starts.

However, if you specify the parent package (here, named ghci-test) on the command line: stack ghci ghci-test, it will only load modules from that package and use the compiled version of child (which it will build, if necessary, prior to switching over to the GHCi prompt).

Some caveats:

  • You will not be able to load anything from the child package into this GHCi session (e.g., :l Child will fail).
  • Changes to the child package won't take effect unless you quit and restart GHCi.

CodePudding user response:

Turns out adding -fobject-code to the .ghci file causes ghci to create object files, which in turn saves it the trouble of recompiling everything every time. Seems like -fno-code is the default.

GHC reference

  • Related