1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-06 05:01:48 +02:00

Add a flag ‘--check’ to verify build determinism

The flag ‘--check’ to ‘nix-store -r’ or ‘nix-build’ will cause Nix to
redo the build of a derivation whose output paths are already valid.
If the new output differs from the original output, an error is
printed.  This makes it easier to test if a build is deterministic.
(Obviously this cannot catch all sources of non-determinism, but it
catches the most common one, namely the current time.)

For example:

  $ nix-build '<nixpkgs>' -A patchelf
  ...
  $ nix-build '<nixpkgs>' -A patchelf --check
  error: derivation `/nix/store/1ipvxsdnbhl1rw6siz6x92s7sc8nwkkb-patchelf-0.6' may not be deterministic: hash mismatch in output `/nix/store/4pc1dmw5xkwmc6q3gdc9i5nbjl4dkjpp-patchelf-0.6.drv'

The --check build fails if not all outputs are valid.  Thus the first
call to nix-build is necessary to ensure that all outputs are valid.

The current outputs are left untouched: the new outputs are either put
in a chroot or diverted to a different location in the store using
hash rewriting.
This commit is contained in:
Eelco Dolstra 2014-02-18 01:01:14 +01:00
parent 4ec626a286
commit 1aa19b24b2
9 changed files with 97 additions and 55 deletions

View file

@ -104,12 +104,13 @@ static PathSet realisePath(const Path & path, bool build = true)
static void opRealise(Strings opFlags, Strings opArgs)
{
bool dryRun = false;
bool repair = false;
BuildMode buildMode = bmNormal;
bool ignoreUnknown = false;
foreach (Strings::iterator, i, opFlags)
if (*i == "--dry-run") dryRun = true;
else if (*i == "--repair") repair = true;
else if (*i == "--repair") buildMode = bmRepair;
else if (*i == "--check") buildMode = bmCheck;
else if (*i == "--ignore-unknown") ignoreUnknown = true;
else throw UsageError(format("unknown flag `%1%'") % *i);
@ -137,7 +138,7 @@ static void opRealise(Strings opFlags, Strings opArgs)
if (dryRun) return;
/* Build all paths at the same time to exploit parallelism. */
store->buildPaths(PathSet(paths.begin(), paths.end()), repair);
store->buildPaths(PathSet(paths.begin(), paths.end()), buildMode);
if (!ignoreUnknown)
foreach (Paths::iterator, i, paths) {