aboutsummaryrefslogtreecommitdiff
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 94410e2bd..883e99ad0 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 6f045dbc3..af54b161e 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);
+
}
}
}