Reputation: 4635
I have the following directory structure:
Most, but not of course all, of this code is written in Global Script, and translated to Haskell by a Haskell program, hsgs2hs.
As such, the code in gsi and gs2hs both depend on the modules from libgs.
Because of somewhat sloppy code organization on my part, the compiler in gs2hs also depends on the front-end modules (parser, type-checker, etc.) from the gsi directory.
Legal aside: If it matters: my code is freely available online, but is not open-source, and its license does not permit redistribution through Hackage. End legal aside.
I can make this directory structure work by running
ghc --make -i../libgs gsi.hs -o gsi
in the gsi directory, and
ghc --make -i../libgs -i ../gsi gs2hs.hs -o gs2hs
in the gs2hs directory.
This has the problem that, every time I do both builds in sequence, GHC recompiles every single module in the libgs directory, and every shared module in the gsi directory, telling me 'flags changed'.
I figure, ok, I should probably be using packages for re-used code in Haskell, right? So I convert libgs to a package:
cabal install --lib --package-env $REPO_ROOT/package.env .
and call it before building gsi and gs2hs-package-env $REPO_ROOT/package.env
to the GHC flags in the gsi and gs2hs directories.No joy!
Now, any change to libgs at all - even just adding a new module to it - causes GHC to recompile every module in the gsi directory, telling me the fundamental module GSI.Value has changed. Even though it actually hasn't; the source code for that module and everything it depends on (which isn't much) is unchanged. Just the hash for the package it's coming from has changed.
How do I stop GHC from recompiling the world constantly, and get it to only recompile things when the result can actually be different?
Upvotes: 2
Views: 224
Reputation: 120711
Add a
libgs.cabal
file to that directory, listing all the modules as exposed modules.
Ok, good.
Add a
libgs/install-all
script that runscabal install --lib --package-env $REPO_ROOT/package.env
Don't do that. As a general rule, never use install --lib
. It's usually better to let Cabal figure out when to install libraries. The easiest way is to put the executables in the package itself. You can have both a library:
section in the .cabal
file as well as arbitrarily many executable: gsi
and executable: gs2hs
ones.
Alternatively, you can keep libgs
a package that doesn't care about executables, but have these in their own package each. Then you don't do any builds in the package directories themselves, but instead put a cabal.project
file in your main src
directory, saying
packages: ./libgs ./gsi ./gs2hs
Then run cabal new-build
in that directory. It'll collectively store the require object files in its .dist-newstyle
directory.
Upvotes: 6