I use a shell.nix file for project development. This file contains custom derivations that I would like to push to cachix to avoid rebuilding them if these are deleted by the garbage collector.
Unfortunately, nix-build shell.nix | cachix push smaret does not work:
% nix-build shell.nix | cachix push smaret
these derivations will be built:
/nix/store/mclpppsyq5fjka6bmp1046n09zv97808-nix-shell.drv
building '/nix/store/mclpppsyq5fjka6bmp1046n09zv97808-nix-shell.drv'...
nobuildPhase
This derivation is not meant to be built, aborting
One workaround is to copy the shell.nix file to default.nix and to replace the pkg.mkShell function with pkg.buildEnv function. But that’s a bit combersome.
Just want to point out that one alternative might be to use Lorri, which automatically creates GC roots so you won’t have to worry about it.
The other option is to use nix-shell --indirect --add-root wherever/is/fine[1].
For getting a handle on the derivation for pushing to cachix, you could get it like this: nix-instantiate shell.nix
[1]: This really is not documented well:
You can find it by following some manpages in this order: nix-shell → nix-instantiate → nix-store, which says:
--add-root path
Causes the result of a realisation (--realise and --force-realise) to be
registered as a root of the garbage collector. The root is stored in path,
which must be inside a directory that is scanned for roots by the garbage
collector (i.e., typically in a subdirectory of /nix/var/nix/gcroots/) unless
the --indirect flag is used.
If there are multiple results, then multiple symlinks will be created by
sequentially numbering symlinks beyond the first one (e.g., foo, foo-2, foo-3,
and so on).
--indirect
In conjunction with --add-root, this option allows roots to be stored outside
of the GC roots directory. This is useful for commands such as nix-build that
place a symlink to the build result in the current directory; such a build
result should not be garbage-collected unless the symlink is removed.
The --indirect flag causes a uniquely named symlink to path to be stored in
/nix/var/nix/gcroots/auto/. For instance,
$ nix-store --add-root /home/eelco/bla/result --indirect -r ...
$ ls -l /nix/var/nix/gcroots/auto
lrwxrwxrwx 1 ... 2005-03-13 21:10 dn54lcypm8f8... -> /home/eelco/bla/result
$ ls -l /home/eelco/bla/result
lrwxrwxrwx 1 ... 2005-03-13 21:10 /home/eelco/bla/result -> /nix/store/1r11343n6qd4...-f-spot-0.0.10
Thus, when /home/eelco/bla/result is removed, the GC root in the auto directory
becomes a dangling symlink and will be ignored by the collector.
Warning
Note that it is not possible to move or rename indirect GC roots, since the
symlink in the auto directory will still point to the old location.