Compiling with optimisations

A seemingly simple question… how does one compile a Cabal project with optimisations? At first, I thought it was just a matter of adding -O2 to ghc-options; my only question was whether this needed to be added to library stanzas or not.

However, when I asked that question on the Discord server, I was pointed towards something quite different instead: the optimization field in cabal.project. What’s more, the documentation for that includes some rather worrying verbiage:

Note that as of GHC 8.0, GHC does not recompile when optimization levels change (see GHC issue #10923), so if you change the optimization level for a local package you may need to blow away your old build products in order to rebuild with the new optimization level.

This is quite vague about what kind of ‘blowing away’ is necessary. It almost sounds like it’s asking me to rm -rf ~/.cabal… unless cabal clean is sufficient? This is really confusing me.

So, my question is: what, precisely, do I need to do/change, in order to compile my Cabal project and all its dependencies with optimisations?

I think you don’t need to worry about dependencies; I believe the optimization field is included in the cabal-hash.txt file, and a hash of that file determines the location of a package’s binaries in the Cabal store. cabal clean should be enough.

As an aside, I have a project in which I build and test for different optimization levels; for this, I use build scripts that call (for example) cabal <cmd> --project-file=cabal.O2.project --builddir=dist-O2 so that I don’t have to blow things away all the time. May or may not be relevant for you.

3 Likes

I posted this related topic a while ago:

So I’d say the optimization field in cabal.project files should be preferred over -O in ghc-options. To enable “-O2” optimizations for all local and non-local dependencies I think you’d have to make a cabal.project file with these contents (note that all packages are already built with optimization level 1 by default):

packages: .
optimization: 2
package *
  optimization: 2

(The difference between non-local and local is essentially whether it is from Hackage or directly from your machine.)

I think the remark about caching is only for local packages and blowing away the old build products should be as easy as running cabal clean. For packages in the cabal store, cabal already tracks configuration options which I think includes optimization level to choose the right built package to use.

Thanks both! I’ve gotten further information elsewhere that -O2 is in fact of questionable benefit in any case, so I guess this doesn’t matter as much as I thought, but I’m less confused now.

You can get more useful hints about options, missing fields etc. by running cabal check in your project.

1 Like