如何正确使用nix-shell并避免"倾斜非常大的路径"?

Zim*_*i48 7 ocaml nix

基于我的读数(特别是维基这篇博客文章),我想出了下面default.nix,我和加载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
    '';
}
Run Code Online (Sandbox Code Playgroud)

但它总是打印一个警告:

warning: dumping very large path (> 256 MiB); this may run out of memory
Run Code Online (Sandbox Code Playgroud)

并且需要很长时间才能加载(nix-shell启动后第一次呼叫约45 秒,后续呼叫约2秒).

这条消息是什么意思?当我在Google上查找它时,我发现了一些GitHub问题,但没有以一种易于理解的方式表达.

我可以加快加载并删除此消息吗?在我看来,我做错了什么.

是否有关于编写这种我可能不知道的开发环境的一般性建议?

小智 10

可能src属性(当前目录)非常大.nix-shell将在每次调用时将其复制到Nix商店,这可能不是您想要/需要的.解决方法是写:

src = if lib.inNixShell then null else ./.;
Run Code Online (Sandbox Code Playgroud)

(lib来自Nixpkgs).

这样,./.将在您调用时复制nix-build,但在运行时不会复制nix-shell.


小智 5

聚会迟到了,但是(因为我无法评论niksnut正确答案)如果您想向srcNix 商店添加一些子集,过滤掉大/不需要的文件,我想提一下处理这个问题的方法。

这种方法使用lib.cleanSource和朋友来自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}
  '';
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,shellSrc指的是表示包含存储路径的属性集./.,但没有vendor子目录(cleanVendor)和无.git.svn,文件结尾的~,和其他的编辑器/ VCS相关的东西(cleanSource)。

查看lib/sources.nix了解更多过滤路径的方法。