diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2016-12-07 13:16:06 +0100 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2016-12-07 13:16:06 +0100 |
commit | 8bdf83f936adae6f2c907a6d2541e80d4120f051 (patch) | |
tree | 17b49383bec8578c307ed3e47fe27db24c3f4171 /src/libstore/build.cc | |
parent | ceeedb58d23950f0ae3944484bca331e5cbb8053 (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.cc | 24 |
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)); |