about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2005-01-19T15·02+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2005-01-19T15·02+0000
commitef5f254a55a2d6db09d3d0549ed45701558027e0 (patch)
tree0d494367c124e760a27f822c7faeb5bc5ec86a98
parent06c77bf7a861221d41b5db9fad3002f13a14ed0e (diff)
* `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.

-rw-r--r--src/libstore/normalise.cc40
-rw-r--r--src/libstore/normalise.hh14
-rw-r--r--src/nix-env/main.cc4
-rw-r--r--src/nix-store/main.cc3
4 files changed, 37 insertions, 24 deletions
diff --git a/src/libstore/normalise.cc b/src/libstore/normalise.cc
index 9424bd24ab..090794ba57 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<PseudoGoal> 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 c5257f9b9d..96f546aaaa 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 4d2ad0c897..d332108cc5 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 12b61c76f7..7c86395a64 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");
     }