diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index 95552a361c..feca410f4e 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 b3c658c295..e6105947f9 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 5d5e9efcfe..020a7135b6 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 b6746689e3..02089c929f 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(); diff --git a/tests/Makefile.am b/tests/Makefile.am index 608ffec19c..4256625d9d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -30,4 +30,4 @@ EXTRA_DIST = $(TESTS) \ dependencies.nix.in dependencies.builder*.sh \ locking.nix.in locking.builder.sh \ parallel.nix.in parallel.builder.sh \ - build-hook.nix.in + build-hook.nix.in build-hook.hook.sh \ No newline at end of file