summary refs log tree commit diff
path: root/src/libexpr
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2012-01-04 16:22:25 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2012-01-04 16:22:25 +0000
commitadaf64a99b0a882249e35768c3f4fe3de104cbb2 (patch)
tree89b3becb5f9197f3d453355262549ea8bf08b9d2 /src/libexpr
parent63227d434cefaa9faeb14afe28ebeb9b2d449ee2 (diff)
parent9936da6b546d1ce643eca21ac76c6e7d568de1c2 (diff)
downloadguix-adaf64a99b0a882249e35768c3f4fe3de104cbb2.tar.gz
* Merge the multiple-outputs-sandbox branch (svn merge --reintegrate
  ^/nix/branches/multiple-outputs-sandbox).  Multiple output support
  still isn't complete, but it wasn't complete in the trunk either, so
  it doesn't hurt.

Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval.cc4
-rw-r--r--src/libexpr/primops.cc49
2 files changed, 27 insertions, 26 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 2b97b76fb7..bba14bc354 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -148,8 +148,6 @@ EvalState::EvalState()
     nrAttrsets = nrOpUpdates = nrOpUpdateValuesCopied = 0;
     deepestStack = (char *) -1;
 
-    createBaseEnv();
-    
     allowUnsafeEquality = getEnv("NIX_NO_UNSAFE_EQ", "") == "";
 
 #if HAVE_BOEHMGC
@@ -188,6 +186,8 @@ EvalState::EvalState()
     foreach (Strings::iterator, i, paths) addToSearchPath(*i);
     addToSearchPath("nix=" + nixDataDir + "/nix/corepkgs");
     searchPathInsertionPoint = searchPath.begin();
+
+    createBaseEnv();
 }
 
 
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 66173cdaf0..21c9fb351d 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -356,27 +356,31 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
            inputs to ensure that they are available when the builder
            runs. */
         if (path.at(0) == '=') {
-            path = string(path, 1);
-            PathSet refs; computeFSClosure(*store, path, refs);
+            /* !!! This doesn't work if readOnlyMode is set. */
+            PathSet refs; computeFSClosure(*store, string(path, 1), refs);
             foreach (PathSet::iterator, j, refs) {
                 drv.inputSrcs.insert(*j);
                 if (isDerivation(*j))
-                    drv.inputDrvs[*j] = singleton<StringSet>("out");
+                    drv.inputDrvs[*j] = store->queryDerivationOutputNames(*j);
             }
         }
 
         /* See prim_unsafeDiscardOutputDependency. */
-        bool useDrvAsSrc = false;
-        if (path.at(0) == '~') {
-            path = string(path, 1);
-            useDrvAsSrc = true;
+        else if (path.at(0) == '~')
+            drv.inputSrcs.insert(string(path, 1));
+
+        /* Handle derivation outputs of the form ‘!<name>!<path>’. */
+        else if (path.at(0) == '!') {
+            size_t index = path.find("!", 1);
+            drv.inputDrvs[string(path, index + 1)].insert(string(path, 1, index - 1));
         }
 
-        assert(isStorePath(path));
+        /* Handle derivation contexts returned by
+           ‘builtins.storePath’. */
+        else if (isDerivation(path))
+            drv.inputDrvs[path] = store->queryDerivationOutputNames(path);
 
-        debug(format("derivation uses `%1%'") % path);
-        if (!useDrvAsSrc && isDerivation(path))
-            drv.inputDrvs[path] = singleton<StringSet>("out");
+        /* Otherwise it's a source file. */
         else
             drv.inputSrcs.insert(path);
     }
@@ -447,10 +451,8 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v)
     state.mkAttrs(v, 1 + drv.outputs.size());
     mkString(*state.allocAttr(v, state.sDrvPath), drvPath, singleton<PathSet>("=" + drvPath));
     foreach (DerivationOutputs::iterator, i, drv.outputs) {
-        /* The output path of an output X is ‘<X>Path’,
-           e.g. ‘outPath’. */
-        mkString(*state.allocAttr(v, state.symbols.create(i->first + "Path")),
-            i->second.path, singleton<PathSet>(drvPath));
+        mkString(*state.allocAttr(v, state.symbols.create(i->first)),
+            i->second.path, singleton<PathSet>("!" + i->first + "!" + drvPath));
     }
     v.attrs->sort();
 }
@@ -1042,15 +1044,6 @@ void EvalState::createBaseEnv()
     addPrimOp("__getEnv", 1, prim_getEnv);
     addPrimOp("__trace", 2, prim_trace);
 
-    // Derivations
-    addPrimOp("derivationStrict", 1, prim_derivationStrict);
-
-    /* Add a wrapper around the derivation primop that computes the
-       `drvPath' and `outPath' attributes lazily. */
-    string s = "attrs: let res = derivationStrict attrs; in attrs // { drvPath = res.drvPath; outPath = res.outPath; type = \"derivation\"; }";
-    mkThunk_(v, parseExprFromString(s, "/"));
-    addConstant("derivation", v);
-
     // Paths
     addPrimOp("__toPath", 1, prim_toPath);
     addPrimOp("__storePath", 1, prim_storePath);
@@ -1099,6 +1092,14 @@ void EvalState::createBaseEnv()
     addPrimOp("__parseDrvName", 1, prim_parseDrvName);
     addPrimOp("__compareVersions", 2, prim_compareVersions);
 
+    // Derivations
+    addPrimOp("derivationStrict", 1, prim_derivationStrict);
+
+    /* Add a wrapper around the derivation primop that computes the
+       `drvPath' and `outPath' attributes lazily. */
+    mkThunk_(v, parseExprFromFile(findFile("nix/derivation.nix")));
+    addConstant("derivation", v);
+
     /* Now that we've added all primops, sort the `builtins' attribute
        set, because attribute lookups expect it to be sorted. */
     baseEnv.values[0]->attrs->sort();