mkShell and envvar with $PWD

I’m trying to find a way of setting an envvar to $PWD/foobar in mkShell like this:

mkShell {
  buildInputs = [ ... ];

  FOO = ./. + "/foobar";
}

but then I get

error: while evaluating the attribute 'FOO' of the derivation 'nix-shell' at /nix/store/fb31dnfdl5s9kxgmn4dfbkas9zbr6gcr-source/pkgs/build-support/mkshell/default.nix:28:3:
getting attributes of path '/home/magnus/my-proj/foobar': No such file or directory

How do I get around thing?

The tools I’ll use in the shell will create the folder when needed, so it doesn’t have to exist.

Will I have to make Nix create the folder? (How???)

Is there some way to put the $PWD into an envar that doesn’t trigger a check for existence of the path?

There seems to be some misunderstanding. ./. refers to the directory of the nix file it appears in. The file location you are constructing to reference a source file or directory will be copied to /nix/store and the resulting path (the one with a hash) will appear as the value of $FOO. Thus it absolutely does have to exist for this expression to make sense.

If you indeed want that location to be relative to the environment variable $PWD at runtime, just write it as such:

FOO = "$PWD/foobar";

Note how this is of type string in the nix language, not a path. Eventually paths end up as strings, because this is the only thing your unixoid OS deals with, but it makes a difference for nix.

If you instead need it to refer to some file relative to the current nix file at runtime, that is, impurely, you can use toString ./foobar. In that case the path expression is converted to an actual dumb string and is not copied to /nix/store.

I tried writing "$PWD" in my shell.nix, and got exactly that value, i.e. the envvar’s value was $PWD, not expanded into the value of $PWD.

Anyway, I found a solution in

FOO = toString ./. + "/foobar";
3 Likes