Stack: nix add-gc-roots does not work under nixos?

Created on 31 Mar 2019  路  9Comments  路  Source: commercialhaskell/stack

General summary/comments

When I build by stack project under nixos, it re-downloads GHC every time I do garbage collection.

Steps to reproduce

$ git clone [email protected]:turion/rhine.git
[...]
$ cd rhine/rhine
$ git checkout stack_nix_gc_roots_bug 
[...]
$ cat stack.yaml 
resolver: lts-12.26
nix:
  enable: true
  add-gc-roots: true

$ stack build
[...]
$ find . -name "*gc*"

$ nix-collect-garbage
finding garbage collector roots...
deleting garbage...
deleting '/nix/store/d9syi687jirk386a9hgr96yqhw6mx243-ghc-8.4.4'
deleting '/nix/store/s7p0wfbdfbq307zgifhnh6w8sfjvy64y-patchelf-0.9'
deleting '/nix/store/4r7rxlb5ingbcwr57aziswmyscpbgjj7-ghc-8.4.4-doc'
deleting '/nix/store/9z1b1ldrhxh7brsi6fxnyjm7gk8kiynv-bash-interactive-4.4-p23-dev'
deleting '/nix/store/c3kwd2jyv11ng84lrxgs3pfascl9bwr2-ghc-8.4.4-src.tar.xz.drv'
deleting '/nix/store/trash'
deleting unused links...
note: currently hard linking saves -0.00 MiB
5 store paths deleted, 1549.44 MiB freed

$ stack build
these paths will be fetched (114.69 MiB download, 1535.52 MiB unpacked):
  /nix/store/4r7rxlb5ingbcwr57aziswmyscpbgjj7-ghc-8.4.4-doc
  /nix/store/9z1b1ldrhxh7brsi6fxnyjm7gk8kiynv-bash-interactive-4.4-p23-dev
  /nix/store/d9syi687jirk386a9hgr96yqhw6mx243-ghc-8.4.4
  /nix/store/s7p0wfbdfbq307zgifhnh6w8sfjvy64y-patchelf-0.9
  /nix/store/y83grpq99ssdd3n53q9zfid8slxrankg-stdenv-linux
copying path '/nix/store/9z1b1ldrhxh7brsi6fxnyjm7gk8kiynv-bash-interactive-4.4-p23-dev' from 'https://cache.nixos.org'...
copying path '/nix/store/s7p0wfbdfbq307zgifhnh6w8sfjvy64y-patchelf-0.9' from 'https://cache.nixos.org'...
copying path '/nix/store/4r7rxlb5ingbcwr57aziswmyscpbgjj7-ghc-8.4.4-doc' from 'https://cache.nixos.org'...
copying path '/nix/store/y83grpq99ssdd3n53q9zfid8slxrankg-stdenv-linux' from 'https://cache.nixos.org'...
copying path '/nix/store/d9syi687jirk386a9hgr96yqhw6mx243-ghc-8.4.4' from 'https://cache.nixos.org'...

I use nixos-unstable.

$ stack --version
1.9.3 x86_64 hpack-0.31.2
build nix bug

All 9 comments

I also tried adding the option in the global ~/.stack/config.yaml, but that didn't help either.

stack build --nix-add-gc-roots doesn't work either.

At first I thought this might've been a case of confusing documentation since we specify "packages" as being nix-add-gc-roots's target:

$ stack --nix-help
Usage: stack [--[no-]nix] [--[no-]nix-pure] [--nix-packages NAMES]
             [--nix-shell-file FILE] [--nix-shell-options OPTIONS]
             [--nix-path PATH_OPTIONS] [--[no-]nix-add-gc-roots] OTHER ARGUMENTS
  Only showing --nix* options.

Available options:
  --[no-]nix               Enable/disable use of a Nix-shell. Implies
                           'system-ghc: true'
  --[no-]nix-pure          Enable/disable use of a pure Nix-shell. Implies
                           '--nix' and 'system-ghc: true'
  --nix-packages NAMES     List of packages that should be available in the
                           nix-shell (space separated)
  --nix-shell-file FILE    Nix file to be used to launch a nix-shell (for
                           regular Nix users)
  --nix-shell-options OPTIONS
                           Additional options passed to nix-shell
  --nix-path PATH_OPTIONS  Additional options to override NIX_PATH parts
                           (notably 'nixpkgs')
  --[no-]nix-add-gc-roots  Enable/disable addition of packages to the nix GC
                           roots so nix-collect-garbage doesn't remove them

So I expected transformers to survive garbage collection (since that's listed in your build-depends stanza) and not ghc, but when I tried it looked like neither were spared.

$ stack --version
Version 1.9.3, Git revision 40cf7b37526b86d1676da82167ea8758a854953b (6211 commits) x86_64 hpack-0.31.1

$ nix --version
nix (Nix) 2.1.3

(On Debian testing)

I'm by no-means a nix expert so it could be I've missed something, but this seems like a bug to me too.

Thanks for the detailed steps to reproduce and well-spotted @turion!

It seems to happen in NixOS 19.09 as well. Anyone any idea why/how?

I get the same behavior on Ubuntu Linux with Stack 2.1.3.1. I set add-gc-roots: true but no nix-gc-symlinks directory is created.

Poked around a bit: stack is passing --add-root to nix-shell correctly, but the option is ignored. This is being tracked as nixos/nix#1982.

In this comment @lheckemann mentions that a possible workaround is to run a command like nix-store -r /nix/store/$hash-$name --add-root ./root-name --indirect to manually create a Nix GC root. In Stack鈥檚 case, I鈥檓 not sure how you鈥檇 figure out which $hash-$name to use. When I run Stack with --verbose, I can see that its nix-shell invocation looks like

Run process: /Users/bdesham/.nix-profile/bin/nix-shell --pure --indirect --add-root .stack-work/nix-gc-symlinks/gc-root -E "with (import <nixpkgs> {}); let inputs = [pcre pkg-config zlib haskell.compiler.ghc865 git gcc gmp]; libPath = lib.makeLibraryPath inputs; stackExtraArgs = lib.concatMap (pkg: [ ''--extra-lib-dirs=${lib.getLib pkg}/lib'' ''--extra-include-dirs=${lib.getDev pkg}/include'' ]) inputs; in runCommand ''myEnv'' { buildInputs = lib.optional stdenv.isLinux glibcLocales ++ inputs; STACK_PLATFORM_VARIANT=''nix''; STACK_IN_NIX_SHELL=1; LD_LIBRARY_PATH = libPath;STACK_IN_NIX_EXTRA_ARGS = stackExtraArgs; LANG=\"en_US.UTF-8\";} \"\"" --run "'/nix/store/hs881lhlv0c86a7bvvx8r04yv7a9jkh7-stack-2.1.3.1/bin/stack' $STACK_IN_NIX_EXTRA_ARGS '--internal-re-exec-version=2.1.3.1' '--verbose' 'build'"

This nixpkgs issue suggests that it should be possible to create a GC root by moving the shell creation information into a shell.nix file, calling nix-instantiate on that file (and asking that tool to create a GC root), and then calling nix-shell on the file to actually run the shell. This might be a workaround for Stack, although (1) I鈥檓 not sure whether this technique will create a GC root either; (2) it seems like it would require nontrivial changes to Stack鈥檚 Nix integration; and (3) there is some problem with doing this, as evidenced by the fact that that nixpkgs issue is still open.

Maybe a lighter-weight workaround would be for Stack to call nix-shell in such a way that the shell鈥檚 store path is displayed. Then it should be possible to feed that path to nix-store -r.

Note that this is due to https://github.com/NixOS/nix/issues/2208

Stack could do something like:

nix-instantiate shell.nix --show-trace  --indirect --add-root "$(pwd)/"shell.drv
nix-shell $(readlink $(pwd)/shell.drv)
Was this page helpful?
0 / 5 - 0 ratings

Related issues

abhinav picture abhinav  路  4Comments

rrnewton picture rrnewton  路  4Comments

jwaldmann picture jwaldmann  路  4Comments

sjakobi picture sjakobi  路  3Comments

domenkozar picture domenkozar  路  3Comments