From ef5f254a55a2d6db09d3d0549ed45701558027e0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 19 Jan 2005 15:02:02 +0000 Subject: [PATCH] * `nix-store --build' now builds its arguments in parallel instead of sequentially (within the limits set by `--jobs'). This should greatly improve the utilisation of the build farm when doing Nixpkgs builds. --- src/libstore/normalise.cc | 40 ++++++++++++++++++++++++--------------- src/libstore/normalise.hh | 14 +++++++------- src/nix-env/main.cc | 4 +++- src/nix-store/main.cc | 3 ++- 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/libstore/normalise.cc b/src/libstore/normalise.cc index 9424bd24a..090794ba5 100644 --- a/src/libstore/normalise.cc +++ b/src/libstore/normalise.cc @@ -163,7 +163,7 @@ public: /* Loop until the specified top-level goal has finished. Returns true if it has finished succesfully. */ - bool run(GoalPtr topGoal); + bool run(const Goals & topGoals); /* Wait for input to become available. */ void waitForInput(); @@ -697,7 +697,7 @@ string showPaths(const PathSet & paths) i != paths.end(); ++i) { if (s.size() != 0) s += ", "; - s += *i; + s += "`" + *i + "'"; } return s; } @@ -915,7 +915,7 @@ bool DerivationGoal::prepareBuild() void DerivationGoal::startBuilder() { startNest(nest, lvlInfo, - format("building path(s) `%1%'") % showPaths(outputPaths(drv.outputs))) + format("building path(s) %1%") % showPaths(outputPaths(drv.outputs))) /* Right platform? */ if (drv.platform != thisSystem) @@ -1664,17 +1664,18 @@ void Worker::waitForBuildSlot(GoalPtr goal, bool reallyWait) } -bool Worker::run(GoalPtr topGoal) +bool Worker::run(const Goals & _topGoals) { - assert(topGoal); - /* Wrap the specified top-level goal in a pseudo-goal so that we can check whether it succeeded. */ shared_ptr pseudo(new PseudoGoal(*this)); - pseudo->addWaitee(topGoal); - - /* For now, we have only one top-level goal. */ - topGoals.insert(topGoal); + for (Goals::iterator i = _topGoals.begin(); + i != _topGoals.end(); ++i) + { + assert(*i); + pseudo->addWaitee(*i); + topGoals.insert(*i); + } startNest(nest, lvlDebug, format("entered goal loop")); @@ -1773,13 +1774,20 @@ void Worker::waitForInput() ////////////////////////////////////////////////////////////////////// -void buildDerivation(const Path & drvPath) +void buildDerivations(const PathSet & drvPaths) { - startNest(nest, lvlDebug, format("building `%1%'") % drvPath); + startNest(nest, lvlDebug, + format("building %1%") % showPaths(drvPaths)); Worker worker; - if (!worker.run(worker.makeDerivationGoal(drvPath))) - throw Error(format("build of derivation `%1%' failed") % drvPath); + + Goals goals; + for (PathSet::const_iterator i = drvPaths.begin(); + i != drvPaths.end(); ++i) + goals.insert(worker.makeDerivationGoal(*i)); + + if (!worker.run(goals)) + throw Error(format("build failed")); } @@ -1789,6 +1797,8 @@ void ensurePath(const Path & path) if (isValidPath(path)) return; Worker worker; - if (!worker.run(worker.makeSubstitutionGoal(path))) + Goals goals; + goals.insert(worker.makeSubstitutionGoal(path)); + if (!worker.run(goals)) throw Error(format("path `%1%' does not exist and cannot be created") % path); } diff --git a/src/libstore/normalise.hh b/src/libstore/normalise.hh index c5257f9b9..96f546aaa 100644 --- a/src/libstore/normalise.hh +++ b/src/libstore/normalise.hh @@ -3,13 +3,13 @@ #include "storeexpr.hh" -/* Perform the specified derivation, if necessary. That is, do - whatever is necessary to create the output paths of the - derivation. If the output paths already exists, we're done. If - they have substitutes, we can use those instead. Otherwise, the - build action described by the derivation is performed, after - recursively building any sub-derivations. */ -void buildDerivation(const Path & drvPath); +/* Perform the specified derivations, if necessary. That is, do + whatever is necessary to create the output paths of the derivation. + If the output paths already exists, we're done. If they have + substitutes, we can use those instead. Otherwise, the build action + described by the derivation is performed, after recursively + building any sub-derivations. */ +void buildDerivations(const PathSet & drvPaths); /* Ensure that a path exists, possibly by instantiating it by realising a substitute. */ diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc index 4d2ad0c89..d332108cc 100644 --- a/src/nix-env/main.cc +++ b/src/nix-env/main.cc @@ -223,7 +223,9 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs, /* Realise the resulting store expression. */ debug(format("building user environment")); - buildDerivation(topLevelDrv.drvPath); + PathSet drvPaths; + drvPaths.insert(topLevelDrv.drvPath); + buildDerivations(drvPaths); /* Switch the current user environment to the output path. */ debug(format("switching to new user environment")); diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc index 12b61c76f..7c86395a6 100644 --- a/src/nix-store/main.cc +++ b/src/nix-store/main.cc @@ -32,10 +32,11 @@ static void opBuild(Strings opFlags, Strings opArgs) { if (!opFlags.empty()) throw UsageError("unknown flag"); + buildDerivations(PathSet(opArgs.begin(), opArgs.end())); + for (Strings::iterator i = opArgs.begin(); i != opArgs.end(); i++) { - buildDerivation(*i); Derivation drv = derivationFromPath(*i); cout << format("%1%\n") % findOutput(drv, "out"); }