summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi4
-rw-r--r--nix/libstore/build.cc14
2 files changed, 16 insertions, 2 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 01363c1d13..cd4e550ef3 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -4332,6 +4332,10 @@ substitutes are genuine (@pxref{Substitutes}), or whether the build result
of a package is deterministic. @xref{Invoking guix challenge}, for more
background information and tools.
+When used in conjunction with @option{--keep-failed}, the differing
+output is kept in the store, under @file{/gnu/store/@dots{}-check}.
+This makes it easy to look for differences between the two results.
+
@item --derivations
@itemx -d
Return the derivation paths, not the output paths, of the given
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
index dd8660dffe..d51705b48f 100644
--- a/nix/libstore/build.cc
+++ b/nix/libstore/build.cc
@@ -2431,8 +2431,18 @@ void DerivationGoal::registerOutputs()
if (buildMode == bmCheck) {
if (!store->isValidPath(path)) continue;
ValidPathInfo info = worker.store.queryPathInfo(path);
- if (hash.first != info.hash)
- throw Error(format("derivation `%1%' may not be deterministic: hash mismatch in output `%2%'") % drvPath % path);
+ if (hash.first != info.hash) {
+ if (settings.keepFailed) {
+ Path dst = path + "-check";
+ if (pathExists(dst)) deletePath(dst);
+ if (rename(actualPath.c_str(), dst.c_str()))
+ throw SysError(format("renaming `%1%' to `%2%'") % actualPath % dst);
+ throw Error(format("derivation `%1%' may not be deterministic: output `%2%' differs from ‘%3%’")
+ % drvPath % path % dst);
+ } else
+ throw Error(format("derivation `%1%' may not be deterministic: output `%2%' differs")
+ % drvPath % path);
+ }
continue;
}