Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Build simple haskell library using nix

Tags:

haskell

nix

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.

like image 390
phil Avatar asked Apr 17 '17 01:04

phil


1 Answers

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.

like image 69
ppb Avatar answered Oct 05 '22 04:10

ppb