about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libexpr/primops.cc18
-rw-r--r--src/libstore/build.cc71
2 files changed, 77 insertions, 12 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 94410e2bdade..883e99ad0dfb 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -949,6 +949,20 @@ static Expr prim_unsafeDiscardStringContext(EvalState & state, const ATermVector
     return makeStr(s, PathSet());
 }
 
+static Expr prim_ExprToString ( EvalState & state, const ATermVector & args)
+{
+	return makeStr ( atPrint ( evalExpr ( state, args [ 0 ] ) ) );
+}
+
+static Expr prim_StringToExpr ( EvalState & state, const ATermVector & args)
+{
+	string s;
+	PathSet l;
+	if (! matchStr ( evalExpr ( state, args[0] ), s, l )) {
+		throw EvalError("__stringToExpr needs string argument!");
+	}
+	return toATerm ( s );
+}
 
 /*************************************************************
  * Primop registration
@@ -975,6 +989,10 @@ void EvalState::addPrimOps()
     addPrimOp("throw", 1, prim_throw);
     addPrimOp("__getEnv", 1, prim_getEnv);
     addPrimOp("__trace", 2, prim_trace);
+    
+    // Expr <-> String
+    addPrimOp("__exprToString", 1, prim_ExprToString);
+    addPrimOp("__stringToExpr", 1, prim_StringToExpr);
 
     addPrimOp("relativise", 2, prim_relativise);
 
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 6f045dbc3774..af54b161e283 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -100,6 +100,7 @@ protected:
     {
         nrFailed = 0;
         exitCode = ecBusy;
+	forceInputs = false;
     }
 
     virtual ~Goal()
@@ -107,6 +108,8 @@ protected:
         trace("goal destroyed");
     }
 
+    bool forceInputs;
+
 public:
     virtual void work() = 0;
 
@@ -141,6 +144,11 @@ public:
        (important!), etc. */
     virtual void cancel() = 0;
 
+    void setForceInputs(bool x)
+    {
+       forceInputs = x;
+    }
+
 protected:
     void amDone(ExitCode result);
 };
@@ -745,7 +753,7 @@ public:
     {
         return drvPath;
     }
-    
+
 private:
     /* The states. */
     void init();
@@ -812,7 +820,6 @@ DerivationGoal::DerivationGoal(const Path & drvPath, Worker & worker)
     trace("created");
 }
 
-
 DerivationGoal::~DerivationGoal()
 {
     /* Careful: we should never ever throw an exception from a
@@ -825,7 +832,6 @@ DerivationGoal::~DerivationGoal()
     }
 }
 
-
 void DerivationGoal::killChild()
 {
     if (pid != -1) {
@@ -905,8 +911,10 @@ void DerivationGoal::haveDerivation()
 
     /* If they are all valid, then we're done. */
     if (invalidOutputs.size() == 0) {
-        amDone(ecSuccess);
-        return;
+        if(! forceInputs) {
+	    amDone(ecSuccess);
+	    return;
+	}
     }
 
     /* If this is a fixed-output derivation, it is possible that some
@@ -950,8 +958,10 @@ void DerivationGoal::outputsSubstituted()
     nrFailed = 0;
 
     if (checkPathValidity(false).size() == 0) {
-        amDone(ecSuccess);
-        return;
+        if (! forceInputs){
+		amDone(ecSuccess);
+		return;
+	}
     }
 
     /* Otherwise, at least one of the output paths could not be
@@ -960,13 +970,43 @@ void DerivationGoal::outputsSubstituted()
     /* The inputs must be built before we can build this goal. */
     /* !!! but if possible, only install the paths that we need */
     for (DerivationInputs::iterator i = drv.inputDrvs.begin();
-         i != drv.inputDrvs.end(); ++i)
-        addWaitee(worker.makeDerivationGoal(i->first));
+         i != drv.inputDrvs.end(); ++i){
+	GoalPtr newGoal = worker.makeDerivationGoal(i->first);
+	newGoal->setForceInputs(forceInputs);
+        addWaitee(newGoal);
+    }
 
     for (PathSet::iterator i = drv.inputSrcs.begin();
          i != drv.inputSrcs.end(); ++i)
         addWaitee(worker.makeSubstitutionGoal(*i));
 
+    /* Actually, I do some work twice just to be on the safe side */
+    string s = drv.env["exportBuildReferencesGraph"]; 
+    Strings ss = tokenizeString(s);
+    if (ss.size() % 2 !=0)
+	throw BuildError(format("odd number of tokens in `exportBuildReferencesGraph': `%1%'") % s); 
+    for (Strings::iterator i = ss.begin(); i != ss.end(); ) {
+	string fileName = *i++;
+	Path storePath=*i++;
+	
+        if (!isInStore(storePath))
+            throw BuildError(format("`exportBuildReferencesGraph' contains a non-store path `%1%'")
+                % storePath);
+        storePath = toStorePath(storePath);
+        if (!store->isValidPath(storePath))
+            throw BuildError(format("`exportBuildReferencesGraph' contains an invalid path `%1%'")
+                % storePath);
+        
+        /* Build-time closure should be in dependencies 
+	 * We really want just derivation, its closure
+	 * and outputs. Looks like we should build it.
+	 * */
+
+	GoalPtr newGoal = worker.makeDerivationGoal(storePath);
+	newGoal->setForceInputs(true);
+        addWaitee(newGoal);
+    }
+
     state = &DerivationGoal::inputsRealised;
 }
 
@@ -984,6 +1024,12 @@ void DerivationGoal::inputsRealised()
         return;
     }
 
+    /* Maybe we just wanted to force build of inputs */
+    if (checkPathValidity(false).size() == 0) {
+        amDone(ecSuccess);
+        return;
+    }
+
     /* Okay, try to build.  Note that here we don't wait for a build
        slot to become available, since we don't need one if there is a
        build hook. */
@@ -1623,7 +1669,7 @@ void DerivationGoal::startBuilder()
     s = drv.env["exportBuildReferencesGraph"];
     ss = tokenizeString(s);
     if (ss.size() % 2 != 0)
-        throw BuildError(format("odd number of tokens in `exportReferencesGraph': `%1%'") % s);
+        throw BuildError(format("odd number of tokens in `exportBuildReferencesGraph': `%1%'") % s);
     for (Strings::iterator i = ss.begin(); i != ss.end(); ) {
         string fileName = *i++;
         checkStoreName(fileName); /* !!! abuse of this function */
@@ -1631,11 +1677,11 @@ void DerivationGoal::startBuilder()
         /* Check that the store path is valid. */
         Path storePath = *i++;
         if (!isInStore(storePath))
-            throw BuildError(format("`exportReferencesGraph' contains a non-store path `%1%'")
+            throw BuildError(format("`exportBuildReferencesGraph' contains a non-store path `%1%'")
                 % storePath);
         storePath = toStorePath(storePath);
         if (!store->isValidPath(storePath))
-            throw BuildError(format("`exportReferencesGraph' contains an invalid path `%1%'")
+            throw BuildError(format("`exportBuildReferencesGraph' contains an invalid path `%1%'")
                 % storePath);
 
         /* Write closure info to `fileName'. */
@@ -1648,6 +1694,7 @@ void DerivationGoal::startBuilder()
 			for (DerivationOutputs::iterator k=deriv.outputs.begin(); 
 			    k != deriv.outputs.end(); k++) {
 				refs.insert(k->second.path);
+				
 			}
 		}
 	}