When defining a new package (see 定义软件包), you will probably find yourself spending some time debugging and tweaking the build until it succeeds. To do that, you need to operate the build commands yourself in an environment as close as possible to the one the build daemon uses.
To that end, the first thing to do is to use the --keep-failed or
-K option of
guix build, which will keep the failed build
tree in /tmp or whatever directory you specified as
From there on, you can
cd to the failed build tree and source the
environment-variables file, which contains all the environment
variable definitions that were in place when the build failed. So let’s say
you’re debugging a build failure in package
foo; a typical session
would look like this:
$ guix build foo -K … build fails $ cd /tmp/guix-build-foo.drv-0 $ source ./environment-variables $ cd foo-1.2
Now, you can invoke commands as if you were the daemon (almost) and troubleshoot your build process.
Sometimes it happens that, for example, a package’s tests pass when you run them manually but they fail when the daemon runs them. This can happen because the daemon runs builds in containers where, unlike in our environment above, network access is missing, /bin/sh does not exist, etc. (see 设置构建环境).
In such cases, you may need to run inspect the build process from within a container similar to the one the build daemon creates:
$ guix build -K foo … $ cd /tmp/guix-build-foo.drv-0 $ guix shell --no-grafts -C -D foo strace gdb [env]# source ./environment-variables [env]# cd foo-1.2
guix shell -C creates a container and spawns a new shell in
it (see Invoking guix shell). The
strace gdb part adds the
gdb commands to the container, which you may
find handy while debugging. The --no-grafts option makes sure we
get the exact same environment, with ungrafted packages (see 安全更新, for more info on grafts).
To get closer to a container like that used by the build daemon, we can remove /bin/sh:
[env]# rm /bin/sh
(Don’t worry, this is harmless: this is all happening in the throw-away
container created by
strace command is probably not in the search path, but we can
[env]# $GUIX_ENVIRONMENT/bin/strace -f -o log make check
In this way, not only you will have reproduced the environment variables the daemon uses, you will also be running the build process in a container similar to the one the daemon uses.