about summary refs log tree commit diff
path: root/src/libstore/normalise.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2005-01-17T16·55+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2005-01-17T16·55+0000
commitf3dc2312501358e29b70bec977fd96f626c46392 (patch)
tree256dc28c596b8d4639c96c4fe66491b8704639d0 /src/libstore/normalise.cc
parentd58a11e019813902b6c4547ca61a127938b2cc20 (diff)
* Removed the `id' attribute hack.
* Formalise the notion of fixed-output derivations, i.e., derivations
  for which a cryptographic hash of the output is known in advance.
  Changes to such derivations should not propagate upwards through the
  dependency graph.  Previously this was done by specifying the hash
  component of the output path through the `id' attribute, but this is
  insecure since you can lie about it (i.e., you can specify any hash
  and then produce a completely different output).  Now the
  responsibility for checking the output is moved from the builder to
  Nix itself.

  A fixed-output derivation can be created by specifying the
  `outputHash' and `outputHashAlgo' attributes, the latter taking
  values `md5', `sha1', and `sha256', and the former specifying the
  actual hash in hexadecimal or in base-32 (auto-detected by looking
  at the length of the attribute value).  MD5 is included for
  compatibility but should be considered deprecated.

* Removed the `drvPath' pseudo-attribute in derivation results.  It's
  no longer necessary.

* Cleaned up the support for multiple output paths in derivation store
  expressions.  Each output now has a unique identifier (e.g., `out',
  `devel', `docs').  Previously there was no way to tell output paths
  apart at the store expression level.

* `nix-hash' now has a flag `--base32' to specify that the hash should
  be printed in base-32 notation.

* `fetchurl' accepts parameters `sha256' and `sha1' in addition to
  `md5'.

* `nix-prefetch-url' now prints out a SHA-1 hash in base-32.  (TODO: a
  flag to specify the hash.)

Diffstat (limited to 'src/libstore/normalise.cc')
-rw-r--r--src/libstore/normalise.cc59
1 files changed, 41 insertions, 18 deletions
diff --git a/src/libstore/normalise.cc b/src/libstore/normalise.cc
index 7907325a97..b016d8d354 100644
--- a/src/libstore/normalise.cc
+++ b/src/libstore/normalise.cc
@@ -702,6 +702,29 @@ static void drain(int fd)
 }
 
 
+PathSet outputPaths(const DerivationOutputs & outputs)
+{
+    PathSet paths;
+    for (DerivationOutputs::const_iterator i = outputs.begin();
+         i != outputs.end(); ++i)
+        paths.insert(i->second.path);
+    return paths;
+}
+
+
+string showPaths(const PathSet & paths)
+{
+    string s;
+    for (PathSet::const_iterator i = paths.begin();
+         i != paths.end(); ++i)
+    {
+        if (s.size() != 0) s += ", ";
+        s += *i;
+    }
+    return s;
+}
+
+
 NormalisationGoal::HookReply NormalisationGoal::tryBuildHook()
 {
     Path buildHook = getEnv("NIX_BUILD_HOOK");
@@ -786,7 +809,7 @@ NormalisationGoal::HookReply NormalisationGoal::tryBuildHook()
         }
 
         printMsg(lvlInfo, format("running hook to build path `%1%'")
-            % *expr.derivation.outputs.begin());
+            % showPaths(outputPaths(expr.derivation.outputs)));
         
         /* Write the information that the hook needs to perform the
            build, i.e., the set of input paths (including closure
@@ -807,9 +830,9 @@ NormalisationGoal::HookReply NormalisationGoal::tryBuildHook()
         writeStringToFile(inputListFN, s);
         
         s = "";
-        for (PathSet::iterator i = expr.derivation.outputs.begin();
+        for (DerivationOutputs::iterator i = expr.derivation.outputs.begin();
              i != expr.derivation.outputs.end(); ++i)
-            s += *i + "\n";
+            s += i->second.path + "\n";
         writeStringToFile(outputListFN, s);
         
         s = "";
@@ -848,7 +871,7 @@ bool NormalisationGoal::prepareBuild()
     /* Obtain locks on all output paths.  The locks are automatically
        released when we exit this function or Nix crashes. */
     /* !!! BUG: this could block, which is not allowed. */
-    outputLocks.lockPaths(expr.derivation.outputs);
+    outputLocks.lockPaths(outputPaths(expr.derivation.outputs));
 
     /* Now check again whether there is a successor.  This is because
        another process may have started building in parallel.  After
@@ -870,11 +893,11 @@ bool NormalisationGoal::prepareBuild()
        running the build hook. */
     
     /* The outputs are referenceable paths. */
-    for (PathSet::iterator i = expr.derivation.outputs.begin();
+    for (DerivationOutputs::iterator i = expr.derivation.outputs.begin();
          i != expr.derivation.outputs.end(); ++i)
     {
-        debug(format("building path `%1%'") % *i);
-        allPaths.insert(*i);
+        debug(format("building path `%1%'") % i->second.path);
+        allPaths.insert(i->second.path);
     }
     
     /* Get information about the inputs (these all exist now). */
@@ -901,9 +924,9 @@ bool NormalisationGoal::prepareBuild()
     /* We can skip running the builder if all output paths are already
        valid. */
     bool fastBuild = true;
-    for (PathSet::iterator i = expr.derivation.outputs.begin();
+    for (DerivationOutputs::iterator i = expr.derivation.outputs.begin();
          i != expr.derivation.outputs.end(); ++i)
-        if (!isValidPath(*i)) { 
+        if (!isValidPath(i->second.path)) { 
             fastBuild = false;
             break;
         }
@@ -921,7 +944,7 @@ bool NormalisationGoal::prepareBuild()
 void NormalisationGoal::startBuilder()
 {
     startNest(nest, lvlInfo,
-        format("building path `%1%'") % *expr.derivation.outputs.begin());
+        format("building path `%1%'") % showPaths(outputPaths(expr.derivation.outputs)))
     
     /* Right platform? */
     if (expr.derivation.platform != thisSystem)
@@ -931,10 +954,10 @@ void NormalisationGoal::startBuilder()
 
     /* If any of the outputs already exist but are not registered,
        delete them. */
-    for (PathSet::iterator i = expr.derivation.outputs.begin(); 
+    for (DerivationOutputs::iterator i = expr.derivation.outputs.begin(); 
          i != expr.derivation.outputs.end(); ++i)
     {
-        Path path = *i;
+        Path path = i->second.path;
         if (isValidPath(path))
             throw Error(format("obstructed build: path `%1%' exists") % path);
         if (pathExists(path)) {
@@ -1054,10 +1077,10 @@ void NormalisationGoal::createClosure()
        output path to determine what other paths it references.  Also make all
        output paths read-only. */
     PathSet usedPaths;
-    for (PathSet::iterator i = expr.derivation.outputs.begin(); 
+    for (DerivationOutputs::iterator i = expr.derivation.outputs.begin(); 
          i != expr.derivation.outputs.end(); ++i)
     {
-        Path path = *i;
+        Path path = i->second.path;
         if (!pathExists(path)) {
             throw BuildError(
                 format("builder for `%1%' failed to produce output path `%2%'")
@@ -1084,6 +1107,7 @@ void NormalisationGoal::createClosure()
 	/* For each path referenced by this output path, add its id to the
 	   closure element and add the id to the `usedPaths' set (so that the
 	   elements referenced by *its* closure are added below). */
+        PathSet outputPaths = ::outputPaths(expr.derivation.outputs);
         for (Paths::iterator j = refPaths.begin();
 	     j != refPaths.end(); ++j)
 	{
@@ -1092,8 +1116,7 @@ void NormalisationGoal::createClosure()
 	    elem.refs.insert(path);
             if (inClosures.find(path) != inClosures.end())
                 usedPaths.insert(path);
-	    else if (expr.derivation.outputs.find(path) ==
-                expr.derivation.outputs.end())
+	    else if (outputPaths.find(path) == outputPaths.end())
 		abort();
         }
 
@@ -1147,9 +1170,9 @@ void NormalisationGoal::createClosure()
        by running the garbage collector. */
     Transaction txn;
     createStoreTransaction(txn);
-    for (PathSet::iterator i = expr.derivation.outputs.begin(); 
+    for (DerivationOutputs::iterator i = expr.derivation.outputs.begin(); 
          i != expr.derivation.outputs.end(); ++i)
-        registerValidPath(txn, *i);
+        registerValidPath(txn, i->second.path);
     registerSuccessor(txn, nePath, nfPath);
     txn.commit();