Skip to content

Instantly share code, notes, and snippets.

@obadz
Created April 28, 2016 20:53
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save obadz/462444fc4fd33400ed64e75a0d409327 to your computer and use it in GitHub Desktop.
Save obadz/462444fc4fd33400ed64e75a0d409327 to your computer and use it in GitHub Desktop.
{ pkgs ? (import <nixpkgs> {}).pkgs
, stdenv ? pkgs.stdenv
, lib ? pkgs.lib
, haskell ? pkgs.haskell
, haskellPackages ? pkgs.haskellPackages
, profiling ? false
}:
rec {
haskellEnv = pkgs.buildEnv {
name = "haskell-env";
paths = [
(haskellPackagesUsed.ghcWithPackages (h: (haskellExtraPackages h) ++ (haskellExtraLibs h)))
];
# Need to pin these two so that they don't get garbage collected as they are required to
# nix-build haskell packages
postBuild = let
pin = [
pkgs.stdenv
(haskell.lib.overrideCabal haskellPackages.hscolour (drv: {
isLibrary = false;
doHaddock = false;
hyperlinkSource = false;
postFixup = "rm -rf $out/lib $out/share $out/nix-support";
}))
];
in "echo ${toString pin} > $out/nix-dependencies.pin";
};
haskellExtraPackages = h: with h; [
cabal2nix
cabal-install
ghc-mod
# ghci-ng
hasktags
# HaRe
haste-compiler # haste-perch, playground
haste-Cabal
haste-cabal-install
hdevtools
hindent
hlint
# hoogle
# hsimport
# leksah
pointfree
stack
stylish-haskell
];
haskellExtraLibs = h: with h; [
aeson
aeson-pretty
base
blaze-builder
bytestring
comonad
containers
errors
extra
hmatrix
http-client
http-client-tls
http-types
HUnit
hxt
hxt-xpath
ipprint
lens
matrix
mtl
QuickCheck
random
roots
scientific
split
statistics
storable-complex
taggy
taggy-lens
tagsoup
text
time
transformers
unordered-containers
utf8-string
vector
wai
warp
wreq
xformat
];
haskellPackagesUsed = haskellPackages.override { overrides = haskellPackageOverrides; };
haskellPackageOverrides = self: super: {
# "hmatrix" = super.hmatrix_0_17_0_1;
# "vector" = super.vector_0_11_0_0;
# "hmatrix-gsl" = super.hmatrix-gsl_0_17_0_0;
# "ghc-mod" = super."ghc-mod".overrideDerivation (attrs: rec {
# src = pkgs.fetchFromGitHub {
# owner = "kazu-yamamoto";
# repo = "ghc-mod";
# rev = "e0044a3697b4ffa8c454c93c93711a3b1c0cc791";
# sha256 = "0i9h7kq23ss5afzdavwvh7h2abg9g6hcz2rwd9xyqbmm3k6ayrl1";
# };
# });
# "ghc-exactprint" = super."ghc-exactprint".overrideDerivation (attrs: rec {
# version = "0.4.1.0";
# sha256 = "66346a89296d720c03a3daa442d96634a73f604c6f06e60b786698403d6c74a7";
# });
# "HaRe" = super."HaRe".overrideDerivation (attrs: rec {
# version = "0.8.2.0";
# sha256 = "66346a89296d720c03a3daa442d96634a73f604c6f06e60b786698403d6c74a7";
# nativeBuildInputs = (lib.filter (x: x.name != "haskell-token-utils") attrs.nativeBuildInputs) ++ super."ghc-exactprint";
# });
};
}
@obadz
Copy link
Author

obadz commented Apr 28, 2016

In ~/.nixpkgs/config.nix, I have:

let
  haskell = import <config/haskell.nix> { };
in
{
  allowUnfree = true;
  packageOverrides = pkgs: rec {
    haskellEnv = haskell.haskellEnv;
  };
}

I install this thing with:

$ nix-env -iA nixpkgs.haskellEnv

and add this to my ~/.bash_profile:

export NIX_PATH=""
export NIX_PATH="$NIX_PATH:config=$HOME/src/nix/config" # Contains haskell.nix
export NIX_PATH="$NIX_PATH:nixos-config=$HOME/src/nix/config/configuration.nix"
export NIX_PATH="$NIX_PATH:nixpkgs=$HOME/src/nix/pkgs"
export NIX_PATH="$NIX_PATH:nixos=$HOME/src/nix/pkgs/nixos"
export NIX_PATH="$NIX_PATH:haskell=$HOME/src/haskell"

# Please ghc-mod:
if type -p ghc >/dev/null
then
    NIX_GHC_VERSION="$(ghc --numeric-version)"
    export NIX_GHC_LIBDIR="$(dirname $(type -p ghc))/../lib/ghc-${NIX_GHC_VERSION}"
fi

I can still use the method described here (https://gist.github.com/obadz/eeb852fef550a1fba697) to nix-build local, interdependent packages. My <haskell/default.nix> now looks a lot simpler:

{ pkgs            ? (import <nixpkgs> { }).pkgs
, lib             ? pkgs.lib
, haskellPackages ? (import <config/haskell.nix> { }).haskellPackagesUsed
, haskellLib      ? pkgs.haskell.lib
}:

let
  cabalFilter = src: path: type:
    let isIn = prefix: (lib.hasPrefix ((toString src) + "/" + prefix) (toString path));
        bn = baseNameOf path;
    in
      !(lib.hasSuffix "~" bn) &&
      !(lib.hasPrefix "." bn) &&
      !(isIn ".cabal-sandbox") &&
      !(isIn ".git") &&
      !(isIn ".stack-work") &&
      !(isIn "cabal.sandbox.config") &&
      !(isIn "dist");
  drvs = rec {
    project-A  = haskellPackages.callPackage ./project-A {};
    project-B  = haskellPackages.callPackage ./project-B {};
    project-C  = haskellPackages.callPackage ./project-C { inherit project-A projectB; };
  };
in lib.mapAttrs (drvName: drv: drv.overrideDerivation (o: { src = builtins.filterSource (cabalFilter o.src) o.src; })) drvs

…and nix-build <haskell> -A project-C still works but for day-to-day development I use cabal like you would on any OS (with sandboxes if I need to build interdependent projects) and I no longer need to start emacs in nix-shell.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment