aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2016-12-07 13:16:06 +0100
committerEelco Dolstra <edolstra@gmail.com>2016-12-07 13:16:06 +0100
commit8bdf83f936adae6f2c907a6d2541e80d4120f051 (patch)
tree17b49383bec8578c307ed3e47fe27db24c3f4171 /src/libstore/build.cc
parentceeedb58d23950f0ae3944484bca331e5cbb8053 (diff)
Add an option to make non-determinism non-fatal
That is, when build-repeat > 0, and the output of two rounds differ, then print a warning rather than fail the build. This is primarily to let Hydra check reproducibility of all packages.
Diffstat (limited to 'src/libstore/build.cc')
-rw-r--r--src/libstore/build.cc24
1 files changed, 13 insertions, 11 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 300f6ac00..84fbf1c18 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -1272,6 +1272,8 @@ void DerivationGoal::inputsRealised()
build hook. */
state = &DerivationGoal::tryToBuild;
worker.wakeUp(shared_from_this());
+
+ result = BuildResult();
}
@@ -1421,6 +1423,8 @@ void DerivationGoal::buildDone()
debug(format("builder process for ‘%1%’ finished") % drvPath);
+ result.timesBuilt++;
+
/* So the child is gone now. */
worker.childTerminated(this);
@@ -2909,17 +2913,15 @@ void DerivationGoal::registerOutputs()
assert(prevInfos.size() == infos.size());
for (auto i = prevInfos.begin(), j = infos.begin(); i != prevInfos.end(); ++i, ++j)
if (!(*i == *j)) {
+ result.isNonDeterministic = true;
Path prev = i->path + checkSuffix;
- if (pathExists(prev))
- throw NotDeterministic(
- format("output ‘%1%’ of ‘%2%’ differs from ‘%3%’ from previous round")
- % i->path % drvPath % prev);
- else
- throw NotDeterministic(
- format("output ‘%1%’ of ‘%2%’ differs from previous round")
- % i->path % drvPath);
+ auto msg = pathExists(prev)
+ ? fmt("output ‘%1%’ of ‘%2%’ differs from ‘%3%’ from previous round", i->path, drvPath, prev)
+ : fmt("output ‘%1%’ of ‘%2%’ differs from previous round", i->path, drvPath);
+ if (settings.get("enforce-determinism", true))
+ throw NotDeterministic(msg);
+ printError(msg);
}
- abort(); // shouldn't happen
}
if (settings.keepFailed) {
@@ -2932,7 +2934,6 @@ void DerivationGoal::registerOutputs()
throw SysError(format("renaming ‘%1%’ to ‘%2%’") % i.second.path % dst);
}
}
-
}
if (curRound < nrRounds) {
@@ -3792,12 +3793,13 @@ void LocalStore::buildPaths(const PathSet & drvPaths, BuildMode buildMode)
worker.run(goals);
PathSet failed;
- for (auto & i : goals)
+ for (auto & i : goals) {
if (i->getExitCode() != Goal::ecSuccess) {
DerivationGoal * i2 = dynamic_cast<DerivationGoal *>(i.get());
if (i2) failed.insert(i2->getDrvPath());
else failed.insert(dynamic_cast<SubstitutionGoal *>(i.get())->getStorePath());
}
+ }
if (!failed.empty())
throw Error(worker.exitStatus(), "build of %s failed", showPaths(failed));