Debug a failed derivation with `breakpointHook` and `cntr`

Thanks for the tricks.

@jonringer If you want to fix phases like fixupPhase, do you run nix-shell as root to be allowed to write in /nix/store? – EDIT-- Oh, I just read this great documentation, and they give the trick to setup a $out in a temporary folder like:

$ cd some_empty_folder # Important to avoid errors during unpack phase
$ export out=~/tmpdev/bc-build/out
$ source $stdenv/setup # loads the environment variable (`PATH`...) of the derivation to ensure we are not using the system variables
$ set +e # To ensure the shell does not quit on errors/Ctrl+C ($stdenv/setup runs `set -e`)
$ set -x # Optional, if you want to display all commands that are run 
$ genericBuild

or if we just want to run a few phases only:

phases="buildPhase checkPhase" genericBuild

Note that if the derivation does not use the default genericBuild system, you can obtain the exact command by using:

$ nix show-derivation $(nix-instantiate .)

and checking what is the builder (usually it’s bash) and the arguments args (usually contains the name of the script to run).

@jamesbrock Is it possible to obtain the definition of the phases from there? If I manually redefine my phase like installPhase = ''mkdir -p $out/bin; cp myfile $out/bin/myfile'';, I can do echo $installPhase (without even exec), but I can’t write:

$ declare -f buildPhase

to check the default implementation of a phase, while this work in a nix shell.

Note to myself: the list of phases is in variable $phases, and by default if this variable is empty the full list is given here or can be checked in the source code. For each phase (say installPhase for the example), the default builder will first check if there is a variable with the name $installPhase (this arrives if you overwrite the default phase) and run in that case:

[nix-shell]$ eval "$installPhase"

(You want both eval and "..." otherwise it won’t do what you expect, see here) Otherwise it will run the default function installPhase:

[nix-shell]$ installPhase

If the phase is the special unpackPhase, it also goes to the $sourceRoot directory (proof here):

cp $sourceRoot
4 Likes