Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use nix-shell properly and avoid "dumping very large path"?

Tags:

ocaml

nix

Based on my readings (notably the wiki and this blog post), I have come up with the following default.nix that I load with nix-shell:

with import <nixpkgs> {};

let emacs =
  emacsWithPackages (p : [ p.tuareg ]);
in

stdenv.mkDerivation rec {
    name = "env";

    src = ./.;

    # Customizable development requirements
    buildInputs = [
        pkgconfig
        ocaml
        ocamlPackages.merlin
        ocamlPackages.findlib
        ocamlPackages.lablgtk
        ocamlPackages.camlp5_transitional
        ncurses
        emacs
    ];

    # Customizable development shell setup
    shellHook = ''
        export PATH=`pwd`/bin:$PATH
    '';
}

But it always prints a warning:

warning: dumping very large path (> 256 MiB); this may run out of memory

and takes quite long to load (about 45 seconds the first time I call nix-shell after start-up, about 2 seconds on subsequent calls).

What is the meaning of this message? When I look for it on Google, I find a few GitHub issues but not expressed in a way that is easy to understand for the layman.

Can I speed up the load and remove this message? It seems to me that I'm doing something wrong.

Are there general recommendations on writing this kind of development environment that I might not be aware of?

like image 715
Zimm i48 Avatar asked Sep 07 '16 14:09

Zimm i48


Video Answer


1 Answers

Late to the party, but (since I can't comment on niksnut's correct answer) I wanted to mention a means of handling this if you want to add some subset of src to the Nix store, filtering out large/unneeded files.

This approach uses lib.cleanSource and friends from nixpkgs:

# shell.nix
{ pkgs ? import <nixpkgs> {} }:

with pkgs;

let
  cleanVendorFilter = name: type: 
    type == "directory" && baseNameOf (toString name) == "vendor";
  cleanVendor = src: lib.cleanSourceWith { filter = cleanVendorFilter; inherit src; };
  shellSrc = lib.cleanSource (cleanVendor ./.);
in mkShell {
  name = "my-shell";
  shellHook = ''
    printf 1>&2 '# Hello from store path %s!\n' ${shellSrc}
  '';
}

In the above snippet, shellSrc refers to an attribute set representing a store path that contains ./., but without the vendor subdirectory (cleanVendor) and without .git, .svn, files ending in ~, and other editor/VCS-related stuff (cleanSource).

Check out lib/sources.nix for more ways to filter paths.

like image 142
tomeon Avatar answered Sep 28 '22 04:09

tomeon