diff options
50 files changed, 424 insertions, 100 deletions
diff --git a/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst b/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst new file mode 100644 index 0000000..198dc51 --- /dev/null +++ b/Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst @@ -0,0 +1,9 @@ +CMAKE_BUILD_PARALLEL_LEVEL +-------------------------- + +Specifies the maximum number of concurrent processes to use when building +using the ``cmake --build`` command line +:ref:`Build Tool Mode <Build Tool Mode>`. + +If this variable is defined empty the native build tool's default number is +used. diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst index 2d8869f..2d17bb5 100644 --- a/Help/manual/cmake-env-variables.7.rst +++ b/Help/manual/cmake-env-variables.7.rst @@ -13,6 +13,7 @@ Environment Variables that Control the Build .. toctree:: :maxdepth: 1 + /envvar/CMAKE_BUILD_PARALLEL_LEVEL /envvar/CMAKE_CONFIG_TYPE /envvar/CMAKE_MSVCIDE_RUN_PATH /envvar/CMAKE_OSX_ARCHITECTURES diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 577d321..177acd4 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -159,6 +159,13 @@ following options: ``--build <dir>`` Project binary directory to be built. This is required and must be first. +``-j [<jobs>], --parallel [<jobs>]`` + The maximum number of concurrent processes to use when building. + If ``<jobs>`` is omitted the native build tool's default number is used. + + The :envvar:`CMAKE_BUILD_PARALLEL_LEVEL` environment variable, if set, + specifies a default parallel level when this option is not given. + ``--target <tgt>`` Build ``<tgt>`` instead of default targets. May only be specified once. diff --git a/Help/release/dev/parallel_build_option.rst b/Help/release/dev/parallel_build_option.rst new file mode 100644 index 0000000..2451fd0 --- /dev/null +++ b/Help/release/dev/parallel_build_option.rst @@ -0,0 +1,6 @@ +parallel_build_option +--------------------- + +* The :manual:`cmake(1)` :ref:`Build Tool Mode` (``cmake --build``) gained + ``--parallel [<jobs>]`` and ``-j [<jobs>]`` options to specify a parallel + build level. They map to corresponding options of the native build tool. diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index b2c68e7..fccbc95 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -253,9 +253,9 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) config = "Debug"; } int retVal = cm.GetGlobalGenerator()->Build( - this->SourceDir, this->BinaryDir, this->BuildProject, tar, output, - this->BuildMakeProgram, config, !this->BuildNoClean, false, false, - remainingTime); + cmake::NO_BUILD_PARALLEL_LEVEL, this->SourceDir, this->BinaryDir, + this->BuildProject, tar, output, this->BuildMakeProgram, config, + !this->BuildNoClean, false, false, remainingTime); out << output; // if the build failed then return if (retVal) { diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx index 26e0db9..a9b7adf 100644 --- a/Source/cmCoreTryCompile.cxx +++ b/Source/cmCoreTryCompile.cxx @@ -818,7 +818,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv, // actually do the try compile now that everything is setup int res = this->Makefile->TryCompile( sourceDirectory, this->BinaryDirectory, projectName, targetName, - this->SrcFileSignature, &cmakeFlags, output); + this->SrcFileSignature, cmake::NO_BUILD_PARALLEL_LEVEL, &cmakeFlags, + output); if (erroroc) { cmSystemTools::SetErrorOccured(); } diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx index d2372a7..2389103 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.cxx +++ b/Source/cmGlobalBorlandMakefileGenerator.cxx @@ -51,3 +51,32 @@ void cmGlobalBorlandMakefileGenerator::GetDocumentation( entry.Name = cmGlobalBorlandMakefileGenerator::GetActualName(); entry.Brief = "Generates Borland makefiles."; } + +void cmGlobalBorlandMakefileGenerator::GenerateBuildCommand( + std::vector<std::string>& makeCommand, const std::string& makeProgram, + const std::string& projectName, const std::string& projectDir, + const std::string& targetName, const std::string& config, bool fast, + int /*jobs*/, bool verbose, std::vector<std::string> const& makeOptions) +{ + this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( + makeCommand, makeProgram, projectName, projectDir, targetName, config, + fast, cmake::NO_BUILD_PARALLEL_LEVEL, verbose, makeOptions); +} + +void cmGlobalBorlandMakefileGenerator::PrintBuildCommandAdvice( + std::ostream& os, int jobs) const +{ + if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { + // Borland's make does not support parallel builds + // see http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Make + + /* clang-format off */ + os << + "Warning: Borland's make does not support parallel builds. " + "Ignoring parallel build command line option.\n"; + /* clang-format on */ + } + + this->cmGlobalUnixMakefileGenerator3::PrintBuildCommandAdvice( + os, cmake::NO_BUILD_PARALLEL_LEVEL); +} diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h index 5578d76..85fee74 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.h +++ b/Source/cmGlobalBorlandMakefileGenerator.h @@ -5,6 +5,8 @@ #include "cmGlobalNMakeMakefileGenerator.h" +#include <iosfwd> + /** \class cmGlobalBorlandMakefileGenerator * \brief Write a Borland makefiles. * @@ -21,7 +23,7 @@ public: } ///! Get the name for the generator. - virtual std::string GetName() const + std::string GetName() const override { return cmGlobalBorlandMakefileGenerator::GetActualName(); } @@ -31,17 +33,27 @@ public: static void GetDocumentation(cmDocumentationEntry& entry); ///! Create a local generator appropriate to this Global Generator - virtual cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf); + cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override; /** * Try to determine system information such as shared library * extension, pthreads, byte order etc. */ - virtual void EnableLanguage(std::vector<std::string> const& languages, - cmMakefile*, bool optional); + void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*, + bool optional) override; + + bool AllowNotParallel() const override { return false; } + bool AllowDeleteOnError() const override { return false; } + +protected: + void GenerateBuildCommand( + std::vector<std::string>& makeCommand, const std::string& makeProgram, + const std::string& projectName, const std::string& projectDir, + const std::string& targetName, const std::string& config, bool fast, + int jobs, bool verbose, std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; - virtual bool AllowNotParallel() const { return false; } - virtual bool AllowDeleteOnError() const { return false; } + void PrintBuildCommandAdvice(std::ostream& os, int jobs) const override; }; #endif diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index cf277d5..8a89f36 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1741,7 +1741,7 @@ void cmGlobalGenerator::CheckTargetProperties() } } -int cmGlobalGenerator::TryCompile(const std::string& srcdir, +int cmGlobalGenerator::TryCompile(int jobs, const std::string& srcdir, const std::string& bindir, const std::string& projectName, const std::string& target, bool fast, @@ -1782,7 +1782,7 @@ int cmGlobalGenerator::TryCompile(const std::string& srcdir, } std::string config = mf->GetSafeDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"); - return this->Build(srcdir, bindir, projectName, newTarget, output, "", + return this->Build(jobs, srcdir, bindir, projectName, newTarget, output, "", config, false, fast, false, this->TryCompileTimeout); } @@ -1790,13 +1790,21 @@ void cmGlobalGenerator::GenerateBuildCommand( std::vector<std::string>& makeCommand, const std::string& /*unused*/, const std::string& /*unused*/, const std::string& /*unused*/, const std::string& /*unused*/, const std::string& /*unused*/, - bool /*unused*/, bool /*unused*/, std::vector<std::string> const& /*unused*/) + bool /*unused*/, int /*unused*/, bool /*unused*/, + std::vector<std::string> const& /*unused*/) { makeCommand.push_back( "cmGlobalGenerator::GenerateBuildCommand not implemented"); } -int cmGlobalGenerator::Build(const std::string& /*unused*/, +void cmGlobalGenerator::PrintBuildCommandAdvice(std::ostream& /*os*/, + int /*jobs*/) const +{ + // Subclasses override this method if they e.g want to give a warning that + // they do not support certain build command line options +} + +int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/, const std::string& bindir, const std::string& projectName, const std::string& target, std::string& output, @@ -1832,7 +1840,8 @@ int cmGlobalGenerator::Build(const std::string& /*unused*/, std::vector<std::string> makeCommand; this->GenerateBuildCommand(makeCommand, makeCommandCSTR, projectName, bindir, - target, config, fast, verbose, nativeOptions); + target, config, fast, jobs, verbose, + nativeOptions); // Workaround to convince VCExpress.exe to produce output. if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH && @@ -1846,7 +1855,7 @@ int cmGlobalGenerator::Build(const std::string& /*unused*/, if (clean) { std::vector<std::string> cleanCommand; this->GenerateBuildCommand(cleanCommand, makeCommandCSTR, projectName, - bindir, "clean", config, fast, verbose); + bindir, "clean", config, fast, jobs, verbose); output += "\nRun Clean Command:"; output += cmSystemTools::PrintSingleCommand(cleanCommand); output += "\n"; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 34ed5b0..62c5441 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -147,9 +147,10 @@ public: * Try running cmake and building a file. This is used for dynamically * loaded commands, not as part of the usual build process. */ - int TryCompile(const std::string& srcdir, const std::string& bindir, - const std::string& projectName, const std::string& targetName, - bool fast, std::string& output, cmMakefile* mf); + int TryCompile(int jobs, const std::string& srcdir, + const std::string& bindir, const std::string& projectName, + const std::string& targetName, bool fast, std::string& output, + cmMakefile* mf); /** * Build a file given the following information. This is a more direct call @@ -157,7 +158,7 @@ public: * empty then all is assumed. clean indicates if a "make clean" should be * done first. */ - int Build(const std::string& srcdir, const std::string& bindir, + int Build(int jobs, const std::string& srcdir, const std::string& bindir, const std::string& projectName, const std::string& targetName, std::string& output, const std::string& makeProgram, const std::string& config, bool clean, bool fast, bool verbose, @@ -176,9 +177,11 @@ public: std::vector<std::string>& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, const std::string& targetName, const std::string& config, bool fast, - bool verbose, + int jobs, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>()); + virtual void PrintBuildCommandAdvice(std::ostream& os, int jobs) const; + /** Generate a "cmake --build" call for a given target and config. */ std::string GenerateCMakeBuildCommand(const std::string& target, const std::string& config, diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index 946ed80..f4ecff2 100644 --- a/Source/cmGlobalGhsMultiGenerator.cxx +++ b/Source/cmGlobalGhsMultiGenerator.cxx @@ -273,11 +273,18 @@ void cmGlobalGhsMultiGenerator::GenerateBuildCommand( std::vector<std::string>& makeCommand, const std::string& makeProgram, const std::string& /*projectName*/, const std::string& /*projectDir*/, const std::string& targetName, const std::string& /*config*/, bool /*fast*/, - bool /*verbose*/, std::vector<std::string> const& makeOptions) + int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions) { makeCommand.push_back( this->SelectMakeProgram(makeProgram, this->GetGhsBuildCommand())); + if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { + makeCommand.push_back("-parallel"); + if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { + makeCommand.push_back(std::to_string(jobs)); + } + } + makeCommand.insert(makeCommand.end(), makeOptions.begin(), makeOptions.end()); if (!targetName.empty()) { diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h index 7d4b2ba..c5388ad 100644 --- a/Source/cmGlobalGhsMultiGenerator.h +++ b/Source/cmGlobalGhsMultiGenerator.h @@ -89,7 +89,7 @@ protected: std::vector<std::string>& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, const std::string& targetName, const std::string& config, bool fast, - bool verbose, + int jobs, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>()); private: diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx index 18c45e0..0f41ea1 100644 --- a/Source/cmGlobalJOMMakefileGenerator.cxx +++ b/Source/cmGlobalJOMMakefileGenerator.cxx @@ -52,3 +52,29 @@ void cmGlobalJOMMakefileGenerator::PrintCompilerAdvice( } this->cmGlobalUnixMakefileGenerator3::PrintCompilerAdvice(os, lang, envVar); } + +void cmGlobalJOMMakefileGenerator::GenerateBuildCommand( + std::vector<std::string>& makeCommand, const std::string& makeProgram, + const std::string& projectName, const std::string& projectDir, + const std::string& targetName, const std::string& config, bool fast, + int jobs, bool verbose, std::vector<std::string> const& makeOptions) +{ + std::vector<std::string> jomMakeOptions; + + // Since we have full control over the invocation of JOM, let us + // make it quiet. + jomMakeOptions.push_back(this->MakeSilentFlag); + jomMakeOptions.insert(jomMakeOptions.end(), makeOptions.begin(), + makeOptions.end()); + + // JOM does parallel builds by default, the -j is only needed if a specific + // number is given + // see https://github.com/qt-labs/jom/blob/v1.1.2/src/jomlib/options.cpp + if (jobs == cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { + jobs = cmake::NO_BUILD_PARALLEL_LEVEL; + } + + cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( + makeCommand, makeProgram, projectName, projectDir, targetName, config, + fast, jobs, verbose, jomMakeOptions); +} diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h index 2e8ee29..65f340c 100644 --- a/Source/cmGlobalJOMMakefileGenerator.h +++ b/Source/cmGlobalJOMMakefileGenerator.h @@ -5,6 +5,8 @@ #include "cmGlobalUnixMakefileGenerator3.h" +#include <iosfwd> + /** \class cmGlobalJOMMakefileGenerator * \brief Write a JOM makefiles. * @@ -19,7 +21,7 @@ public: return new cmGlobalGeneratorSimpleFactory<cmGlobalJOMMakefileGenerator>(); } ///! Get the name for the generator. - virtual std::string GetName() const + std::string GetName() const override { return cmGlobalJOMMakefileGenerator::GetActualName(); } @@ -34,12 +36,20 @@ public: * Try to determine system information such as shared library * extension, pthreads, byte order etc. */ - virtual void EnableLanguage(std::vector<std::string> const& languages, - cmMakefile*, bool optional); + void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*, + bool optional) override; + +protected: + void GenerateBuildCommand( + std::vector<std::string>& makeCommand, const std::string& makeProgram, + const std::string& projectName, const std::string& projectDir, + const std::string& targetName, const std::string& config, bool fast, + int jobs, bool verbose, std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; private: void PrintCompilerAdvice(std::ostream& os, std::string const& lang, - const char* envVar) const; + const char* envVar) const override; }; #endif diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx index da683fb..eb66bd1 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.cxx +++ b/Source/cmGlobalNMakeMakefileGenerator.cxx @@ -52,3 +52,40 @@ void cmGlobalNMakeMakefileGenerator::PrintCompilerAdvice( } this->cmGlobalUnixMakefileGenerator3::PrintCompilerAdvice(os, lang, envVar); } + +void cmGlobalNMakeMakefileGenerator::GenerateBuildCommand( + std::vector<std::string>& makeCommand, const std::string& makeProgram, + const std::string& projectName, const std::string& projectDir, + const std::string& targetName, const std::string& config, bool fast, + int /*jobs*/, bool verbose, std::vector<std::string> const& makeOptions) +{ + std::vector<std::string> nmakeMakeOptions; + + // Since we have full control over the invocation of nmake, let us + // make it quiet. + nmakeMakeOptions.push_back(this->MakeSilentFlag); + nmakeMakeOptions.insert(nmakeMakeOptions.end(), makeOptions.begin(), + makeOptions.end()); + + this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( + makeCommand, makeProgram, projectName, projectDir, targetName, config, + fast, cmake::NO_BUILD_PARALLEL_LEVEL, verbose, nmakeMakeOptions); +} + +void cmGlobalNMakeMakefileGenerator::PrintBuildCommandAdvice(std::ostream& os, + int jobs) const +{ + if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { + // nmake does not support parallel build level + // see https://msdn.microsoft.com/en-us/library/afyyse50.aspx + + /* clang-format off */ + os << + "Warning: NMake does not support parallel builds. " + "Ignoring parallel build command line option.\n"; + /* clang-format on */ + } + + this->cmGlobalUnixMakefileGenerator3::PrintBuildCommandAdvice( + os, cmake::NO_BUILD_PARALLEL_LEVEL); +} diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h index 05ab904..4b6382e 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.h +++ b/Source/cmGlobalNMakeMakefileGenerator.h @@ -5,6 +5,8 @@ #include "cmGlobalUnixMakefileGenerator3.h" +#include <iosfwd> + /** \class cmGlobalNMakeMakefileGenerator * \brief Write a NMake makefiles. * @@ -20,7 +22,7 @@ public: cmGlobalNMakeMakefileGenerator>(); } ///! Get the name for the generator. - virtual std::string GetName() const + std::string GetName() const override { return cmGlobalNMakeMakefileGenerator::GetActualName(); } @@ -39,12 +41,22 @@ public: * Try to determine system information such as shared library * extension, pthreads, byte order etc. */ - virtual void EnableLanguage(std::vector<std::string> const& languages, - cmMakefile*, bool optional); + void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*, + bool optional) override; + +protected: + void GenerateBuildCommand( + std::vector<std::string>& makeCommand, const std::string& makeProgram, + const std::string& projectName, const std::string& projectDir, + const std::string& targetName, const std::string& config, bool fast, + int jobs, bool verbose, std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; + + void PrintBuildCommandAdvice(std::ostream& os, int jobs) const override; private: void PrintCompilerAdvice(std::ostream& os, std::string const& lang, - const char* envVar) const; + const char* envVar) const override; }; #endif diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index c19a61c..69bc3be 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -674,7 +674,7 @@ void cmGlobalNinjaGenerator::GenerateBuildCommand( std::vector<std::string>& makeCommand, const std::string& makeProgram, const std::string& /*projectName*/, const std::string& /*projectDir*/, const std::string& targetName, const std::string& /*config*/, bool /*fast*/, - bool verbose, std::vector<std::string> const& makeOptions) + int jobs, bool verbose, std::vector<std::string> const& makeOptions) { makeCommand.push_back(this->SelectMakeProgram(makeProgram)); @@ -682,6 +682,12 @@ void cmGlobalNinjaGenerator::GenerateBuildCommand( makeCommand.push_back("-v"); } + if ((jobs != cmake::NO_BUILD_PARALLEL_LEVEL) && + (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL)) { + makeCommand.push_back("-j"); + makeCommand.push_back(std::to_string(jobs)); + } + makeCommand.insert(makeCommand.end(), makeOptions.begin(), makeOptions.end()); if (!targetName.empty()) { diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index bfff3d9..17b9a7d 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -202,13 +202,11 @@ public: void EnableLanguage(std::vector<std::string> const& languages, cmMakefile* mf, bool optional) override; - void GenerateBuildCommand(std::vector<std::string>& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, bool verbose, - std::vector<std::string> const& makeOptions = + void GenerateBuildCommand( + std::vector<std::string>& makeCommand, const std::string& makeProgram, + const std::string& projectName, const std::string& projectDir, + const std::string& targetName, const std::string& config, bool fast, + int jobs, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; // Setup target names diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index c07f10f..641b760 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -7,7 +7,6 @@ #include <sstream> #include <utility> -#include "cmAlgorithms.h" #include "cmDocumentationEntry.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" @@ -494,31 +493,33 @@ void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( std::vector<std::string>& makeCommand, const std::string& makeProgram, const std::string& /*projectName*/, const std::string& /*projectDir*/, const std::string& targetName, const std::string& /*config*/, bool fast, - bool /*verbose*/, std::vector<std::string> const& makeOptions) + int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions) { + cmMakefile* mf; + if (!this->Makefiles.empty()) { + mf = this->Makefiles[0]; + } else { + cmStateSnapshot snapshot = this->CMakeInstance->GetCurrentSnapshot(); + snapshot.GetDirectory().SetCurrentSource( + this->CMakeInstance->GetHomeDirectory()); + snapshot.GetDirectory().SetCurrentBinary( + this->CMakeInstance->GetHomeOutputDirectory()); + snapshot.SetDefaultDefinitions(); + mf = new cmMakefile(this, snapshot); + } + makeCommand.push_back(this->SelectMakeProgram(makeProgram)); - // Since we have full control over the invocation of nmake, let us - // make it quiet. - if (cmHasLiteralPrefix(this->GetName(), "NMake Makefiles")) { - makeCommand.push_back("/NOLOGO"); + if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { + makeCommand.push_back("-j"); + if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { + makeCommand.push_back(std::to_string(jobs)); + } } + makeCommand.insert(makeCommand.end(), makeOptions.begin(), makeOptions.end()); if (!targetName.empty()) { - cmMakefile* mf; - if (!this->Makefiles.empty()) { - mf = this->Makefiles[0]; - } else { - cmStateSnapshot snapshot = this->CMakeInstance->GetCurrentSnapshot(); - snapshot.GetDirectory().SetCurrentSource( - this->CMakeInstance->GetHomeDirectory()); - snapshot.GetDirectory().SetCurrentBinary( - this->CMakeInstance->GetHomeOutputDirectory()); - snapshot.SetDefaultDefinitions(); - mf = new cmMakefile(this, snapshot); - } - std::string tname = targetName; if (fast) { tname += "/fast"; @@ -528,9 +529,9 @@ void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( conv.ConvertToRelativePath(mf->GetState()->GetBinaryDirectory(), tname); cmSystemTools::ConvertToOutputSlashes(tname); makeCommand.push_back(std::move(tname)); - if (this->Makefiles.empty()) { - delete mf; - } + } + if (this->Makefiles.empty()) { + delete mf; } } diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index f9ce88c..097678f 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -127,13 +127,11 @@ public: std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; } // change the build command for speed - void GenerateBuildCommand(std::vector<std::string>& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, bool verbose, - std::vector<std::string> const& makeOptions = + void GenerateBuildCommand( + std::vector<std::string>& makeCommand, const std::string& makeProgram, + const std::string& projectName, const std::string& projectDir, + const std::string& targetName, const std::string& config, bool fast, + int jobs, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; /** Record per-target progress information. */ diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 205e0d0..51e9ab1 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -764,7 +764,7 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( std::vector<std::string>& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, const std::string& targetName, const std::string& config, bool fast, - bool verbose, std::vector<std::string> const& makeOptions) + int jobs, bool verbose, std::vector<std::string> const& makeOptions) { // Select the caller- or user-preferred make program, else MSBuild. std::string makeProgramSelected = @@ -805,7 +805,7 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( // Use devenv to build solutions containing Intel Fortran projects. cmGlobalVisualStudio7Generator::GenerateBuildCommand( makeCommand, makeProgram, projectName, projectDir, targetName, config, - fast, verbose, makeOptions); + fast, jobs, verbose, makeOptions); return; } @@ -813,6 +813,7 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( std::string realTarget = targetName; // msbuild.exe CxxOnly.sln /t:Build /p:Configuration=Debug /target:ALL_BUILD + // /m if (realTarget.empty()) { realTarget = "ALL_BUILD"; } @@ -841,6 +842,17 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand( makeCommand.push_back(configArg); makeCommand.push_back(std::string("/p:VisualStudioVersion=") + this->GetIDEVersion()); + + if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { + if (jobs == cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { + makeCommand.push_back("/m"); + } else { + makeCommand.push_back(std::string("/m:") + std::to_string(jobs)); + } + // Having msbuild.exe and cl.exe using multiple jobs is discouraged + makeCommand.push_back("/p:CL_MPCount=1"); + } + makeCommand.insert(makeCommand.end(), makeOptions.begin(), makeOptions.end()); } diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index f2501c2..098c8d4 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -24,13 +24,11 @@ public: bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override; bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override; - void GenerateBuildCommand(std::vector<std::string>& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, bool verbose, - std::vector<std::string> const& makeOptions = + void GenerateBuildCommand( + std::vector<std::string>& makeCommand, const std::string& makeProgram, + const std::string& projectName, const std::string& projectDir, + const std::string& targetName, const std::string& config, bool fast, + int jobs, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; ///! create the correct local generator diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 7ff007f..158f484 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -199,7 +199,7 @@ void cmGlobalVisualStudio7Generator::GenerateBuildCommand( std::vector<std::string>& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& /*projectDir*/, const std::string& targetName, const std::string& config, bool /*fast*/, - bool /*verbose*/, std::vector<std::string> const& makeOptions) + int /*jobs*/, bool /*verbose*/, std::vector<std::string> const& makeOptions) { // Select the caller- or user-preferred make program, else devenv. std::string makeProgramSelected = diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index 8d1bdc0..77d4a96 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -55,13 +55,11 @@ public: * Try running cmake and building a file. This is used for dynamically * loaded commands, not as part of the usual build process. */ - void GenerateBuildCommand(std::vector<std::string>& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, bool verbose, - std::vector<std::string> const& makeOptions = + void GenerateBuildCommand( + std::vector<std::string>& makeCommand, const std::string& makeProgram, + const std::string& projectName, const std::string& projectDir, + const std::string& targetName, const std::string& config, bool fast, + int jobs, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; /** diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx index 94cdb38..558ef15 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.cxx +++ b/Source/cmGlobalWatcomWMakeGenerator.cxx @@ -7,6 +7,8 @@ #include "cmState.h" #include "cmake.h" +#include <ostream> + cmGlobalWatcomWMakeGenerator::cmGlobalWatcomWMakeGenerator(cmake* cm) : cmGlobalUnixMakefileGenerator3(cm) { @@ -47,3 +49,31 @@ void cmGlobalWatcomWMakeGenerator::GetDocumentation( entry.Name = cmGlobalWatcomWMakeGenerator::GetActualName(); entry.Brief = "Generates Watcom WMake makefiles."; } + +void cmGlobalWatcomWMakeGenerator::GenerateBuildCommand( + std::vector<std::string>& makeCommand, const std::string& makeProgram, + const std::string& projectName, const std::string& projectDir, + const std::string& targetName, const std::string& config, bool fast, + int /*jobs*/, bool verbose, std::vector<std::string> const& makeOptions) +{ + this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( + makeCommand, makeProgram, projectName, projectDir, targetName, config, + fast, cmake::NO_BUILD_PARALLEL_LEVEL, verbose, makeOptions); +} + +void cmGlobalWatcomWMakeGenerator::PrintBuildCommandAdvice(std::ostream& os, + int jobs) const +{ + if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { + // wmake does not support parallel build level + + /* clang-format off */ + os << + "Warning: Watcom's WMake does not support parallel builds. " + "Ignoring parallel build command line option.\n"; + /* clang-format on */ + } + + this->cmGlobalUnixMakefileGenerator3::PrintBuildCommandAdvice( + os, cmake::NO_BUILD_PARALLEL_LEVEL); +} diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h index e8b3a73..1729bf1 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.h +++ b/Source/cmGlobalWatcomWMakeGenerator.h @@ -8,6 +8,7 @@ #include "cmGlobalGeneratorFactory.h" #include "cmGlobalUnixMakefileGenerator3.h" +#include <iosfwd> #include <string> #include <vector> @@ -47,6 +48,16 @@ public: bool AllowNotParallel() const override { return false; } bool AllowDeleteOnError() const override { return false; } + +protected: + void GenerateBuildCommand( + std::vector<std::string>& makeCommand, const std::string& makeProgram, + const std::string& projectName, const std::string& projectDir, + const std::string& targetName, const std::string& config, bool fast, + int jobs, bool verbose, std::vector<std::string> const& makeOptions = + std::vector<std::string>()) override; + + void PrintBuildCommandAdvice(std::ostream& os, int jobs) const override; }; #endif diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 4481bdc..f69f23e 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -325,7 +325,7 @@ void cmGlobalXCodeGenerator::GenerateBuildCommand( std::vector<std::string>& makeCommand, const std::string& makeProgram, const std::string& projectName, const std::string& /*projectDir*/, const std::string& targetName, const std::string& config, bool /*fast*/, - bool /*verbose*/, std::vector<std::string> const& makeOptions) + int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions) { // now build the test makeCommand.push_back( @@ -356,6 +356,14 @@ void cmGlobalXCodeGenerator::GenerateBuildCommand( } makeCommand.push_back("-configuration"); makeCommand.push_back(!config.empty() ? config : "Debug"); + + if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) { + makeCommand.push_back("-jobs"); + if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) { + makeCommand.push_back(std::to_string(jobs)); + } + } + makeCommand.insert(makeCommand.end(), makeOptions.begin(), makeOptions.end()); } diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 7c51177..f7f4428 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -66,13 +66,11 @@ public: * Try running cmake and building a file. This is used for dynalically * loaded commands, not as part of the usual build process. */ - void GenerateBuildCommand(std::vector<std::string>& makeCommand, - const std::string& makeProgram, - const std::string& projectName, - const std::string& projectDir, - const std::string& targetName, - const std::string& config, bool fast, bool verbose, - std::vector<std::string> const& makeOptions = + void GenerateBuildCommand( + std::vector<std::string>& makeCommand, const std::string& makeProgram, + const std::string& projectName, const std::string& projectDir, + const std::string& targetName, const std::string& config, bool fast, + int jobs, bool verbose, std::vector<std::string> const& makeOptions = std::vector<std::string>()) override; /** Append the subdirectory for the given configuration. */ diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 33e76b2..f41c2f0 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -3269,7 +3269,7 @@ void cmMakefile::EnableLanguage(std::vector<std::string> const& lang, int cmMakefile::TryCompile(const std::string& srcdir, const std::string& bindir, const std::string& projectName, - const std::string& targetName, bool fast, + const std::string& targetName, bool fast, int jobs, const std::vector<std::string>* cmakeArgs, std::string& output) { @@ -3381,7 +3381,7 @@ int cmMakefile::TryCompile(const std::string& srcdir, // finally call the generator to actually build the resulting project int ret = this->GetGlobalGenerator()->TryCompile( - srcdir, bindir, projectName, targetName, fast, output, this); + jobs, srcdir, bindir, projectName, targetName, fast, output, this); this->IsSourceFileTryCompile = false; return ret; diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 9f32c4f..ac7baae 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -102,7 +102,8 @@ public: */ int TryCompile(const std::string& srcdir, const std::string& bindir, const std::string& projectName, const std::string& targetName, - bool fast, const std::vector<std::string>* cmakeArgs, + bool fast, int jobs, + const std::vector<std::string>* cmakeArgs, std::string& output); bool GetIsSourceFileTryCompile() const; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 5bae4e7..801d52d 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2398,7 +2398,7 @@ cmMessenger* cmake::GetMessenger() const return this->Messenger; } -int cmake::Build(const std::string& dir, const std::string& target, +int cmake::Build(int jobs, const std::string& dir, const std::string& target, const std::string& config, const std::vector<std::string>& nativeOptions, bool clean) { @@ -2508,7 +2508,9 @@ int cmake::Build(const std::string& dir, const std::string& target, } #endif - return gen->Build("", dir, projName, target, output, "", config, clean, + gen->PrintBuildCommandAdvice(std::cerr, jobs); + + return gen->Build(jobs, "", dir, projName, target, output, "", config, clean, false, verbose, cmDuration::zero(), cmSystemTools::OUTPUT_PASSTHROUGH, nativeOptions); } diff --git a/Source/cmake.h b/Source/cmake.h index 63dbe9f..6c0d77c 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -119,6 +119,9 @@ public: typedef std::map<std::string, cmInstalledFile> InstalledFilesMap; + static const int NO_BUILD_PARALLEL_LEVEL = -1; + static const int DEFAULT_BUILD_PARALLEL_LEVEL = 0; + /// Default constructor cmake(Role role); /// Destructor @@ -430,7 +433,7 @@ public: cmListFileBacktrace const& backtrace = cmListFileBacktrace()) const; ///! run the --build option - int Build(const std::string& dir, const std::string& target, + int Build(int jobs, const std::string& dir, const std::string& target, const std::string& config, const std::vector<std::string>& nativeOptions, bool clean); diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index b185a1b..9c9f65c 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -22,6 +22,8 @@ #if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE) #include "cmsys/ConsoleBuf.hxx" #endif + +#include <ctype.h> #include <iostream> #include <string.h> #include <string> @@ -49,6 +51,12 @@ static const char* cmDocumentationUsageNote[][2] = { #define CMAKE_BUILD_OPTIONS \ " <dir> = Project binary directory to be built.\n" \ + " -j [<jobs>] --parallel [<jobs>] = Build in parallel using\n" \ + " the given number of jobs. If <jobs> is omitted\n" \ + " the native build tool's default number is used.\n" \ + " The CMAKE_BUILD_PARALLEL_LEVEL environment variable\n" \ + " specifies a default parallel level when this option\n" \ + " is not given.\n" \ " --target <tgt> = Build <tgt> instead of default targets.\n" \ " May only be specified once.\n" \ " --config <cfg> = For multi-configuration tools, choose <cfg>.\n" \ @@ -338,6 +346,7 @@ static int do_build(int ac, char const* const* av) std::cerr << "This cmake does not support --build\n"; return -1; #else + int jobs = cmake::NO_BUILD_PARALLEL_LEVEL; std::string target; std::string config = "Debug"; std::string dir; @@ -348,6 +357,7 @@ static int do_build(int ac, char const* const* av) enum Doing { DoingNone, + DoingJobs, DoingDir, DoingTarget, DoingConfig, @@ -357,6 +367,13 @@ static int do_build(int ac, char const* const* av) for (int i = 2; i < ac; ++i) { if (doing == DoingNative) { nativeOptions.push_back(av[i]); + } else if ((strcmp(av[i], "-j") == 0) || + (strcmp(av[i], "--parallel") == 0)) { + jobs = cmake::DEFAULT_BUILD_PARALLEL_LEVEL; + /* does the next argument start with a number? */ + if ((i + 1 < ac) && (isdigit(*av[i + 1]))) { + doing = DoingJobs; + } } else if (strcmp(av[i], "--target") == 0) { if (!hasTarget) { doing = DoingTarget; @@ -377,6 +394,18 @@ static int do_build(int ac, char const* const* av) doing = DoingNative; } else { switch (doing) { + case DoingJobs: { + unsigned long numJobs = 0; + if (cmSystemTools::StringToULong(av[i], &numJobs)) { + jobs = int(numJobs); + doing = DoingNone; + } else { + std::cerr << "'" << av[i - 1] << "' invalid number '" << av[i] + << "' given.\n\n"; + dir.clear(); + break; + } + } break; case DoingDir: dir = cmSystemTools::CollapseFullPath(av[i]); doing = DoingNone; @@ -396,6 +425,25 @@ static int do_build(int ac, char const* const* av) } } } + + if (jobs == cmake::NO_BUILD_PARALLEL_LEVEL) { + std::string parallel; + if (cmSystemTools::GetEnv("CMAKE_BUILD_PARALLEL_LEVEL", parallel)) { + if (parallel.empty()) { + jobs = cmake::DEFAULT_BUILD_PARALLEL_LEVEL; + } else { + unsigned long numJobs = 0; + if (cmSystemTools::StringToULong(parallel.c_str(), &numJobs)) { + jobs = int(numJobs); + } else { + std::cerr << "'CMAKE_BUILD_PARALLEL_LEVEL' environment variable\n" + << "invalid number '" << parallel << "' given.\n\n"; + dir.clear(); + } + } + } + } + if (dir.empty()) { /* clang-format off */ std::cerr << @@ -410,7 +458,7 @@ static int do_build(int ac, char const* const* av) cmake cm(cmake::RoleInternal); cmSystemTools::SetMessageCallback(cmakemainMessageCallback, &cm); cm.SetProgressCallback(cmakemainProgressCallback, &cm); - return cm.Build(dir, target, config, nativeOptions, clean); + return cm.Build(jobs, dir, target, config, nativeOptions, clean); #endif } diff --git a/Tests/RunCMake/CommandLine/BuildDir--build--parallel-bad-number-result.txt b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-bad-number-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-bad-number-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/BuildDir--build--parallel-bad-number-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-bad-number-stderr.txt new file mode 100644 index 0000000..e73d760 --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-bad-number-stderr.txt @@ -0,0 +1,3 @@ +^'--parallel' invalid number '12ab' given\. ++ +Usage: cmake --build <dir> \[options\] \[-- \[native-options\]\] diff --git a/Tests/RunCMake/CommandLine/BuildDir--build--parallel-good-number-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-good-number-stderr.txt new file mode 100644 index 0000000..3c2c808 --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-good-number-stderr.txt @@ -0,0 +1 @@ +(^$|^Warning: .* does not support parallel builds\. Ignoring parallel build command line option\.) diff --git a/Tests/RunCMake/CommandLine/BuildDir--build--parallel-good-number-trailing--target-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-good-number-trailing--target-stderr.txt new file mode 100644 index 0000000..3c2c808 --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-good-number-trailing--target-stderr.txt @@ -0,0 +1 @@ +(^$|^Warning: .* does not support parallel builds\. Ignoring parallel build command line option\.) diff --git a/Tests/RunCMake/CommandLine/BuildDir--build--parallel-good-number-trailing-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-good-number-trailing-stderr.txt new file mode 100644 index 0000000..3c2c808 --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-good-number-trailing-stderr.txt @@ -0,0 +1 @@ +(^$|^Warning: .* does not support parallel builds\. Ignoring parallel build command line option\.) diff --git a/Tests/RunCMake/CommandLine/BuildDir--build--parallel-no-number-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-no-number-stderr.txt new file mode 100644 index 0000000..3c2c808 --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-no-number-stderr.txt @@ -0,0 +1 @@ +(^$|^Warning: .* does not support parallel builds\. Ignoring parallel build command line option\.) diff --git a/Tests/RunCMake/CommandLine/BuildDir--build--parallel-no-number-trailing--target-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-no-number-trailing--target-stderr.txt new file mode 100644 index 0000000..3c2c808 --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-no-number-trailing--target-stderr.txt @@ -0,0 +1 @@ +(^$|^Warning: .* does not support parallel builds\. Ignoring parallel build command line option\.) diff --git a/Tests/RunCMake/CommandLine/BuildDir--build--parallel-no-number-trailing-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-no-number-trailing-stderr.txt new file mode 100644 index 0000000..3c2c808 --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build--parallel-no-number-trailing-stderr.txt @@ -0,0 +1 @@ +(^$|^Warning: .* does not support parallel builds\. Ignoring parallel build command line option\.) diff --git a/Tests/RunCMake/CommandLine/BuildDir--build-jobs-bad-number-result.txt b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-bad-number-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-bad-number-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/BuildDir--build-jobs-bad-number-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-bad-number-stderr.txt new file mode 100644 index 0000000..c810087 --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-bad-number-stderr.txt @@ -0,0 +1,3 @@ +^'-j' invalid number '12ab' given\. ++ +Usage: cmake --build <dir> \[options\] \[-- \[native-options\]\] diff --git a/Tests/RunCMake/CommandLine/BuildDir--build-jobs-good-number-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-good-number-stderr.txt new file mode 100644 index 0000000..3c2c808 --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-good-number-stderr.txt @@ -0,0 +1 @@ +(^$|^Warning: .* does not support parallel builds\. Ignoring parallel build command line option\.) diff --git a/Tests/RunCMake/CommandLine/BuildDir--build-jobs-good-number-trailing--target-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-good-number-trailing--target-stderr.txt new file mode 100644 index 0000000..3c2c808 --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-good-number-trailing--target-stderr.txt @@ -0,0 +1 @@ +(^$|^Warning: .* does not support parallel builds\. Ignoring parallel build command line option\.) diff --git a/Tests/RunCMake/CommandLine/BuildDir--build-jobs-good-number-trailing-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-good-number-trailing-stderr.txt new file mode 100644 index 0000000..3c2c808 --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-good-number-trailing-stderr.txt @@ -0,0 +1 @@ +(^$|^Warning: .* does not support parallel builds\. Ignoring parallel build command line option\.) diff --git a/Tests/RunCMake/CommandLine/BuildDir--build-jobs-no-number-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-no-number-stderr.txt new file mode 100644 index 0000000..3c2c808 --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-no-number-stderr.txt @@ -0,0 +1 @@ +(^$|^Warning: .* does not support parallel builds\. Ignoring parallel build command line option\.) diff --git a/Tests/RunCMake/CommandLine/BuildDir--build-jobs-no-number-trailing--target-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-no-number-trailing--target-stderr.txt new file mode 100644 index 0000000..3c2c808 --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-no-number-trailing--target-stderr.txt @@ -0,0 +1 @@ +(^$|^Warning: .* does not support parallel builds\. Ignoring parallel build command line option\.) diff --git a/Tests/RunCMake/CommandLine/BuildDir--build-jobs-no-number-trailing-stderr.txt b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-no-number-trailing-stderr.txt new file mode 100644 index 0000000..3c2c808 --- /dev/null +++ b/Tests/RunCMake/CommandLine/BuildDir--build-jobs-no-number-trailing-stderr.txt @@ -0,0 +1 @@ +(^$|^Warning: .* does not support parallel builds\. Ignoring parallel build command line option\.) diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake index d8dbeec..3bb2a89 100644 --- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake +++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake @@ -59,6 +59,29 @@ function(run_BuildDir) ${CMAKE_COMMAND} --build BuildDir-build --target CustomTarget) run_cmake_command(BuildDir--build-multiple-targets ${CMAKE_COMMAND} -E chdir .. ${CMAKE_COMMAND} --build BuildDir-build --target CustomTarget2 --target CustomTarget3) + run_cmake_command(BuildDir--build-jobs-bad-number ${CMAKE_COMMAND} -E chdir .. + ${CMAKE_COMMAND} --build BuildDir-build -j 12ab) + run_cmake_command(BuildDir--build-jobs-good-number ${CMAKE_COMMAND} -E chdir .. + ${CMAKE_COMMAND} --build BuildDir-build -j 2) + run_cmake_command(BuildDir--build-jobs-good-number-trailing--target ${CMAKE_COMMAND} -E chdir .. + ${CMAKE_COMMAND} --build BuildDir-build -j 2 --target CustomTarget) + run_cmake_command(BuildDir--build--parallel-bad-number ${CMAKE_COMMAND} -E chdir .. + ${CMAKE_COMMAND} --build BuildDir-build --parallel 12ab) + run_cmake_command(BuildDir--build--parallel-good-number ${CMAKE_COMMAND} -E chdir .. + ${CMAKE_COMMAND} --build BuildDir-build --parallel 2) + run_cmake_command(BuildDir--build--parallel-good-number-trailing--target ${CMAKE_COMMAND} -E chdir .. + ${CMAKE_COMMAND} --build BuildDir-build --parallel 2 --target CustomTarget) + # No default jobs for Xcode and FreeBSD build command + if(NOT RunCMake_GENERATOR MATCHES "Xcode" AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + run_cmake_command(BuildDir--build-jobs-no-number ${CMAKE_COMMAND} -E chdir .. + ${CMAKE_COMMAND} --build BuildDir-build -j) + run_cmake_command(BuildDir--build-jobs-no-number-trailing--target ${CMAKE_COMMAND} -E chdir .. + ${CMAKE_COMMAND} --build BuildDir-build -j --target CustomTarget) + run_cmake_command(BuildDir--build--parallel-no-number ${CMAKE_COMMAND} -E chdir .. + ${CMAKE_COMMAND} --build BuildDir-build --parallel) + run_cmake_command(BuildDir--build--parallel-no-number-trailing--target ${CMAKE_COMMAND} -E chdir .. + ${CMAKE_COMMAND} --build BuildDir-build --parallel --target CustomTarget) + endif() endfunction() run_BuildDir() |