$ nix-shell hello.nix
bash: make: command not found
[nix-shell]$ echo $baseInputs
But, we have the environment variables that we set in the derivation, like $baseInputs, $buildInputs, $src and so on.
That means we can source our builder.sh, and it will build the derivation. You may get an error in the installation phase, because the user may not have the permission to write to /nix/store:
[nix-shell]$ source builder.sh
- We sourced builder.sh, therefore it ran all the steps including setting up the PATH for us.
- The working directory is no more a temp directory created by nix-build, but the current directory. Therefore, hello-2.9 has been unpacked there.
A builder for nix-shell
First of all, we were able to source builder.sh because it was in our current directory, but that’s not nice. We want the builder.sh that is stored in the nix store, the one that would be used by nix-build. To do so, the right way is to pass the usual environment variable through the derivation.
Note: $builder is already defined, but it’s the bash executable, not our builder.sh. Our builder.sh is an argument to bash.
Second, we don’t want to run the whole builder, we only want it to setup the necessary environment for manually building the project. So we’ll write two files, one for setting up the environment, and the real builder.sh that runs with nix-build.
Additionally, we’ll wrap the phases in functions, it may be useful, and move the set -e to the builder instead of the setup. The set -e is annoying in nix-shell.
The codebase is becoming a little long. You can find all the files in this nixpill10 gist.
Noteworthy is the setup = ./setup.sh; attribute in the derivation, which adds setup.sh to the nix store and as usual, adds a $setup environment variable in the builder.
Thanks to that, we can split builder.sh into setup.sh and builder.sh. What builder.sh does is sourcing $setup and calling the genericBuild function. Everything else is just some bash changes.
Now back to nix-shell:
$ nix-shell hello.nix
[nix-shell]$ source $setup
Now you can run, for example, unpackPhase which unpacks $src and enters the directory. And you can run commands like ./configure, make etc. manually, or run phases with their respective functions.
It’s all that straight, nix-shell builds the .drv file and its input dependencies, then drops into a shell by setting up the environment variables necessary to build the .drv, in particular those passed to the derivation function.
Note that we did never install gcc, make, etc. system-wide. These tools and libraries are available per-build.
Pill 11 is available for reading here.