Как правильно использовать nix-shell и избежать сброса очень большого пути?

На основе моих чтений (в частности, вики и это сообщение в блоге), я придумал следующее 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
    '';
}

Но всегда выводит предупреждение:

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

и загрузка занимает довольно много времени (около 45 секунд при первом вызове nix-shell после запуска, около 2 секунд при последующих вызовах).

В чем смысл этого сообщения? Когда я ищу это в Google, я нахожу несколько проблем с GitHub, но не выраженных в понятной для непрофессионала форме.

Можно ускорить загрузку и убрать это сообщение? Мне кажется, что я что-то не так делаю.

Есть ли общие рекомендации по написанию такой среды разработки, о которых я мог не знать?


person Zimm i48    schedule 07.09.2016    source источник


Ответы (2)


Вероятно, атрибут src (текущий каталог) очень велик. nix-shell будет копировать его в хранилище Nix при каждом вызове, что, вероятно, не то, что вам нужно / нужно. Обходной путь - написать:

src = if lib.inNixShell then null else ./.;

(где lib происходит от Nixpkgs).

Таким образом, ./. будет скопирован при вызове nix-build, но не при запуске nix-shell.

person niksnut    schedule 14.09.2016
comment
Это было очень полезно. Однако не следует ли читать "then null else './.';" вместо "then null else nix;"? - person knedlsepp; 12.04.2017
comment
Разве это не приведет к тому же предупреждению при запуске nix-build? Это проблема, которая возникает у меня даже без использования lib.inNixShell, nix-shell доволен, но nix-build выдает предупреждение (но все еще работает). - person LB2; 21.11.2019

Поздно к вечеринке, но (поскольку я не могу комментировать niksnut правильный ответ) Я хотел бы упомянуть способ решения этой проблемы, если вы хотите добавить некоторое подмножество src в хранилище Nix, отфильтровывая большие / ненужные файлы.

В этом подходе используются 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}
  '';
}

В приведенном выше фрагменте shellSrc относится к набору атрибутов, представляющему путь к магазину, который содержит ./., но без подкаталога vendor (cleanVendor) и без .git, .svn, файлов, заканчивающихся на ~, и других материалов, связанных с редактором / VCS (cleanSource).

Ознакомьтесь с lib / sources.nix, чтобы узнать о других способах фильтрации путей. .

person tomeon    schedule 13.08.2019
comment
Это правильный способ сделать это, но этот ответ выглядит слишком сложным, потому что он касается каталога vendor, о котором OP не упоминает. Было бы лучше сначала показать src = lib.cleanSource ./.;, а затем показать, как можно делать более сложные вещи. - person Neil Mayhew; 29.06.2020