diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libstore/build.cc | 39 | ||||
-rw-r--r-- | src/libstore/store.cc | 8 | ||||
-rw-r--r-- | src/nix-store/main.cc | 10 |
3 files changed, 45 insertions, 12 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 026721f3b9d8..7dd7412e9f21 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -472,9 +472,8 @@ void DerivationGoal::outputsSubstituted() { trace("all outputs substituted (maybe)"); - if (nrFailed > 0 && !tryFallback) { + if (nrFailed > 0 && !tryFallback) throw Error(format("some substitutes for the outputs of derivation `%1%' failed; try `--fallback'") % drvPath); - } nrFailed = 0; @@ -1252,6 +1251,9 @@ private: /* The current substitute. */ Substitute sub; + /* Outgoing references for this path. */ + PathSet references; + /* Pipe for the substitute's standard output/error. */ Pipe logPipe; @@ -1272,6 +1274,7 @@ public: /* The states. */ void init(); + void referencesValid(); void tryNext(); void tryToRun(); void finished(); @@ -1313,13 +1316,35 @@ void SubstitutionGoal::init() return; } - /* !!! build the outgoing references of this path first to - maintain the closure invariant! */ - - /* Otherwise, get the substitutes. */ + /* Read the substitutes. */ subs = querySubstitutes(storePath); - /* Try the first one. */ + /* To maintain the closure invairant, we first have to realise the + paths referenced by this one. */ + queryReferences(storePath, references); + + for (PathSet::iterator i = references.begin(); + i != references.end(); ++i) + addWaitee(worker.makeSubstitutionGoal(*i)); + + if (waitees.empty()) /* to prevent hang (no wake-up event) */ + referencesValid(); + else + state = &SubstitutionGoal::referencesValid; +} + + +void SubstitutionGoal::referencesValid() +{ + trace("all referenced realised"); + + if (nrFailed > 0) + throw Error(format("some references of path `%1%' could not be realised") % storePath); + + for (PathSet::iterator i = references.begin(); + i != references.end(); ++i) + assert(isValidPath(*i)); + tryNext(); } diff --git a/src/libstore/store.cc b/src/libstore/store.cc index 97b7f5fe8ab4..02bf9803b29c 100644 --- a/src/libstore/store.cc +++ b/src/libstore/store.cc @@ -265,8 +265,8 @@ void setReferences(const Transaction & txn, const Path & storePath, void queryReferences(const Path & storePath, PathSet & references) { Paths references2; - if (!isValidPath(storePath)) - throw Error(format("path `%1%' is not valid") % storePath); + // if (!isValidPath(storePath)) + // throw Error(format("path `%1%' is not valid") % storePath); nixDB.queryStrings(noTxn, dbReferences, storePath, references2); references.insert(references2.begin(), references2.end()); } @@ -275,8 +275,8 @@ void queryReferences(const Path & storePath, PathSet & references) void queryReferers(const Path & storePath, PathSet & referers) { Paths referers2; - if (!isValidPath(storePath)) - throw Error(format("path `%1%' is not valid") % storePath); + // if (!isValidPath(storePath)) + // throw Error(format("path `%1%' is not valid") % storePath); nixDB.queryStrings(noTxn, dbReferers, storePath, referers2); referers.insert(referers2.begin(), referers2.end()); } diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc index dc7a6de8b8ec..51e587255003 100644 --- a/src/nix-store/main.cc +++ b/src/nix-store/main.cc @@ -177,19 +177,27 @@ static void opSubstitute(Strings opFlags, Strings opArgs) while (1) { Path srcPath; Substitute sub; + PathSet references; getline(cin, srcPath); if (cin.eof()) break; getline(cin, sub.program); string s; - getline(cin, s); int n; + getline(cin, s); if (!string2Int(s, n)) throw Error("number expected"); while (n--) { getline(cin, s); sub.args.push_back(s); } + getline(cin, s); + if (!string2Int(s, n)) throw Error("number expected"); + while (n--) { + getline(cin, s); + references.insert(s); + } if (!cin || cin.eof()) throw Error("missing input"); subPairs.push_back(pair<Path, Substitute>(srcPath, sub)); + setReferences(txn, srcPath, references); } registerSubstitutes(txn, subPairs); |