I've been interested in Nix for a while, and I thought I would finally try to use it for starting a new haskell project.
I began with the directory structure
project.cabal
src/Lib.hs
Where the cabal file has the following contents:
name: project
version: 0.1.0.0
build-type: Simple
license: MIT
cabal-version: >= 1.18
library
exposed-modules: Lib
build-depends: base < 5
hs-source-dirs: src
default-language: Haskell2010
and Lib.hs has
module Lib where
hello :: Int -> IO ()
hello x = putStrLn (show x)
As you can see, it's quite simple. When I execute cabal build
, it seems to be happy. Note that I'm no haskell expert by any means, so I may be making some beginner mistake here.
To build this with Nix, I've been reading https://github.com/Gabriel439/haskell-nix to get my information. I executed cabal2nix . > default.nix
to get a Nix version of my cabal file. I then created a release.nix
file to actually build it. The contents of the two files are as follows:
default.nix
{ mkDerivation, base, stdenv }:
mkDerivation {
pname = "project";
version = "0.1.0.0";
src = ./.;
libraryHaskellDepends = [ base ];
license = stdenv.lib.licenses.mit;
}
release.nix
let
pkgs = import <nixpkgs> { };
in
pkgs.haskellPackages.callPackage ./default.nix { }
After doing this, I executed nix-build release.nix
and got back
these derivations will be built:
/nix/store/p481alkpm89712n3hnwai0nxhmjrm8b2-project-0.1.0.0.drv
building path(s) ‘/nix/store/yszy2a6wd88pf6zlw0nw99l5wzvc0s9x-project-0.1.0.0’
setupCompilerEnvironmentPhase
Build with /nix/store/d5w12a8bprd2518xnqp1cwh3rbjiagyx-ghc-8.0.1.
unpacking sources
unpacking source archive /nix/store/fsn4b9w54h2jdpv546nwvy82vnkszl1w-project
source root is project
patching sources
compileBuildDriverPhase
setupCompileFlags: -package-db=/tmp/nix-build-project-0.1.0.0.drv-0/package.conf.d -j4 -threaded
[1 of 1] Compiling Main ( /nix/store/4mdp8nhyfddh7bllbi7xszz7k9955n79-Setup.hs, /tmp/nix-build-project-0.1.0.0.drv-0/Main.o )
Linking Setup ...
...
...
Building project-0.1.0.0...
Preprocessing library project-0.1.0.0...
dist/build/Lib_o_split: getDirectoryContents: does not exist (No such file or
directory)
builder for ‘/nix/store/p481alkpm89712n3hnwai0nxhmjrm8b2-project-0.1.0.0.drv’ failed with exit code 1
error: build of ‘/nix/store/p481alkpm89712n3hnwai0nxhmjrm8b2-project-0.1.0.0.drv’ failed
Which of course isn't good. What mistake am I making here? I've been successful in a similar attempt which was building an executable instead of a library, so I suspect it has something to do with that. The github repo I was following was using an executable as well.
I believe by default nix, unlike plain cabal, will try to build any Haskell project using split objects feature, per cabal's manual:
--enable-split-objs
Use the GHC -split-objs feature when building the library. This reduces the final size of the executables that use the library by allowing them to link with only the bits that they use rather than the entire library. The downside is that building the library takes longer and uses considerably more memory.
I'm not too sure as to why that may be failing on your system but depending on your nixpkgs version can be disabled by adding one of:
enableSplitObjs = false;
enableDeadCodeElimination = false;
to the derivation.
For a list of other other attributes / options you can refer to https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/generic-builder.nix Unfortunately I'm not aware of any official documentation describing those in more detail.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With