Adding breakpointHook to nativeBuildInputs of the failing derivation is also a powerful technique ― it allows you to connect with cntr and explore the environment as it was at the point that the derivation's build failed.
Thanks to jamesbrock on the NixOS Discourse, the short of it is:
Add the breakpointHook package to the nativeBuildInputs of a mkDerivation.
nativeBuildInputs = [ breakpointHook ];
Install cntr
nix-env -i cntr
Run your Nix build command, and when it fails, the breakpointHook will output a message like this:
build failed in installPhase with exit code 1
To attach install cntr and run the following command as root:
cntr attach -t command cntr-/nix/store/6vwxqrwq5h1fd3nw4mc61wgk7rppn2qw-jupyterlab-extended
So we run that command as root. The root user doesn’t have a PATH to the cntr command which we installed in our Nix profile, so give it the full path to our single-user-installed cntr.
sudo /home/$USER/.nix-profile/bin/cntr attach -t command cntr-/nix/store/6vwxqrwq5h1fd3nw4mc61wgk7rppn2qw-jupyterlab-extended
And now we’re in the sleeping Nix container.
Note that paths like $out and $TMPDIR are available at this stage along with your usual tools, however, they're under the current directory (/var/lib/cntr), instead of /.
(You can use them like cd $(echo $out | cut -c2-).)
From here, run cntr exec to fully load the build environment.
/home/$USER/.nix-profile/bin/cntr exec
The $TMPDIR directory is where Nix has created the temporary directory for the build 10.
cd $TMPDIR
Now we are fully inside the context of the build, and any commands which we enter in the shell will be as if we had entered that command on a line in the phase (for example, buildPhase) of our derivation when the derivation failed.
Mentioned here in the NixOS Discourse:
I want to also add a few details regarding breakpointHook. It is a really powerful debug hook by @Mic92.
It is enough to put pkgs.breakpointHook into your buildInputs to get it working. In the case of a failure there is an exact “connection” command printed out to the console. You can use this command (cntr) to attach a shell into the build environment. To use it you have to be able to run sudo along with cntr (so you should install cntr package before ;-)).
You can find more interesting details in the @Mic92 NixCon presentation: Jörg 'Mic92' Thalheim - About Nix sandboxes and breakpoints (NixCon 2018)
Here's a link to the relevant section of the manual: https://nixos.org/manual/nixpkgs/stable/#breakpointhook
nix-buildand hence you get the full output with no truncation or aggregation. – Chris Stryczynski Jul 28 '23 at 11:15nix-buildcan execute different build phases, for example inpython3.pkgs.buildPythonPackage. the actual build phases are stored in the variable$phases, so in the nix-shell, seeecho $phases. docs: Building a stdenv package in nix-shell, issues: docs: fix nix-shell commands, docs: Building a stdenv package in nix-shell – milahu Jul 28 '23 at 11:54buildPhaseresults in:no Makefile, doing nothing. Other commands seem to fail withmkdir: cannot create directory ‘/nix/store/kk9irdv2ppca45fzwwz7422vsmbpgga1-HaskellNixCabalStarter-0.1.0.0’: Read-only file system. – Chris Stryczynski Jan 14 '24 at 16:26cmakeConfigurePhase. theRead-only file systemerror is fixed by using different output paths. another problem is thatnix-buildruns the build script withset -eto stop on the first error, but this would exit the interactive bash shell... see also nixos discourse – milahu Jan 15 '24 at 13:21chromiumpackageeval "${unpackPhase:-unpackPhase}"fails withvariable $src or $srcs should point to the sourcebutphases="unpackPhase" genericBuildworks... so probablygenericBuildis better as a generic phase runner – milahu Feb 05 '24 at 12:26