about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libmain/shared.cc19
-rw-r--r--src/libstore/globals.cc2
-rw-r--r--src/libstore/globals.hh3
-rw-r--r--src/libstore/normalise.cc13
4 files changed, 29 insertions, 8 deletions
diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc
index 95552a361cfc..feca410f4eb7 100644
--- a/src/libmain/shared.cc
+++ b/src/libmain/shared.cc
@@ -118,16 +118,29 @@ static void initAndRun(int argc, char * * argv)
             ++i;
             if (i == args.end()) throw UsageError("`--log-type' requires an argument");
             setLogType(*i);
-        } else if (arg == "--build-output" || arg == "-B")
+        }
+        else if (arg == "--build-output" || arg == "-B")
             buildVerbosity = lvlError; /* lowest */
         else if (arg == "--help") {
             printHelp();
             return;
-        } else if (arg == "--version") {
+        }
+        else if (arg == "--version") {
             cout << format("%1% (Nix) %2%") % programId % NIX_VERSION << endl;
             return;
-        } else if (arg == "--keep-failed" || arg == "-K")
+        }
+        else if (arg == "--keep-failed" || arg == "-K")
             keepFailed = true;
+        else if (arg == "--max-jobs" || arg == "-j") {
+            ++i;
+            if (i == args.end()) throw UsageError("`--max-jobs' requires an argument");
+            istringstream str(*i);
+            int n;
+            str >> n;
+            if (!str || !str.eof() || n < 0)
+                throw UsageError(format("`--max-jobs' requires a non-negative integer"));
+            maxBuildJobs = n;
+        }
         else remaining.push_back(arg);
     }
 
diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc
index b3c658c29562..e6105947f9ee 100644
--- a/src/libstore/globals.cc
+++ b/src/libstore/globals.cc
@@ -9,3 +9,5 @@ string nixDBPath = "/UNINIT";
 bool keepFailed = false;
 
 Verbosity buildVerbosity = lvlDebug;
+
+unsigned int maxBuildJobs = 1;
diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh
index 5d5e9efcfec5..020a7135b66c 100644
--- a/src/libstore/globals.hh
+++ b/src/libstore/globals.hh
@@ -32,5 +32,8 @@ extern bool keepFailed;
 /* Verbosity level for build output. */
 extern Verbosity buildVerbosity;
 
+/* Maximum number of parallel build jobs.  0 means unlimited. */
+extern unsigned int maxBuildJobs;
+
 
 #endif /* !__GLOBALS_H */
diff --git a/src/libstore/normalise.cc b/src/libstore/normalise.cc
index b6746689e301..02089c929fdf 100644
--- a/src/libstore/normalise.cc
+++ b/src/libstore/normalise.cc
@@ -284,6 +284,9 @@ bool Normaliser::startBuild(Path nePath)
 {
     checkInterrupt();
 
+    if (maxBuildJobs > 0 && building.size() >= maxBuildJobs)
+        return false;
+
     Goals::iterator goalIt = goals.find(nePath);
     assert(goalIt != goals.end());
     Goal & goal(goalIt->second);
@@ -414,11 +417,6 @@ bool Normaliser::startBuild(Path nePath)
             format("build hook died with status %1%") % status);
     }
 
-    /* Right platform? */
-    if (goal.expr.derivation.platform != thisSystem)
-        throw Error(format("a `%1%' is required, but I am a `%2%'")
-		    % goal.expr.derivation.platform % thisSystem);
-
     /* Otherwise, start the build in a child process. */
     startBuildChild(goal);
 
@@ -428,6 +426,11 @@ bool Normaliser::startBuild(Path nePath)
 
 void Normaliser::startBuildChild(Goal & goal)
 {
+    /* Right platform? */
+    if (goal.expr.derivation.platform != thisSystem)
+        throw Error(format("a `%1%' is required, but I am a `%2%'")
+		    % goal.expr.derivation.platform % thisSystem);
+
     /* If any of the outputs already exist but are not registered,
        delete them. */
     for (PathSet::iterator i = goal.expr.derivation.outputs.begin();