Passing “-j” to Haskell’s “cabal” through Nix

I’ve building Haskell project using Nix. Just “flake.nix” not “haskell.nix”. I didn’t set this up but I’m confident enough at this point to add packages in the override set using “callHackage” or straight from a GitHub url etc. I also pass a bunch of warning options to all our local packages.

However I have noticed that the ‘nix -j auto build’ is far slower than a ‘cabal -j build all’. Also the cabal build keeps my CPU usage higher. Whilst it seems that GHC struggles to use more than one thread when building an individual module, When I run a ‘cabal -j build’ in verbose mode (with -v), I see cabal is calling ‘ghc —make’ with the ‘-j’ option, so ghc uses multiple threads when there’s an opportunity to compile multiple modules in parallel.

What I think is happening is that ‘nix -j auto build’ is happily building packages in parallel when they’re not dependent on each other, but is only using one thread to build each package, maybe because it’s not passing ‘-j’ to ‘ghc —make’.

Does this sound about right, and is there any way to parallelise the build of individual packages?

The haskell infrastructure should respect the --cores Nix option, which is designed for this purpose.

By default the Haskell stuff in Nixpkgs will build profiling libraries and tests for all (most) packages. If you want the speed of nix build to match cabal build, you’ll likely need to turn off profiling libs and tests.