Skip to content

Commit

Permalink
Merge topic 'parallel_build_option'
Browse files Browse the repository at this point in the history
1ab3881 cmake: Add options for parallel builds to --build mode

Acked-by: Kitware Robot <[email protected]>
Acked-by: Henry Schreiner <[email protected]>
Merge-request: !1962
  • Loading branch information
bradking authored and kwrobot committed May 29, 2018
2 parents 42752d0 + 1ab3881 commit f248f8a
Show file tree
Hide file tree
Showing 50 changed files with 424 additions and 100 deletions.
9 changes: 9 additions & 0 deletions Help/envvar/CMAKE_BUILD_PARALLEL_LEVEL.rst
Original file line number Diff line number Diff line change
@@ -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.
1 change: 1 addition & 0 deletions Help/manual/cmake-env-variables.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions Help/manual/cmake.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
6 changes: 6 additions & 0 deletions Help/release/dev/parallel_build_option.rst
Original file line number Diff line number Diff line change
@@ -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.
6 changes: 3 additions & 3 deletions Source/CTest/cmCTestBuildAndTestHandler.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion Source/cmCoreTryCompile.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
29 changes: 29 additions & 0 deletions Source/cmGlobalBorlandMakefileGenerator.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
24 changes: 18 additions & 6 deletions Source/cmGlobalBorlandMakefileGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include "cmGlobalNMakeMakefileGenerator.h"

#include <iosfwd>

/** \class cmGlobalBorlandMakefileGenerator
* \brief Write a Borland makefiles.
*
Expand All @@ -21,7 +23,7 @@ class cmGlobalBorlandMakefileGenerator : public cmGlobalUnixMakefileGenerator3
}

///! Get the name for the generator.
virtual std::string GetName() const
std::string GetName() const override
{
return cmGlobalBorlandMakefileGenerator::GetActualName();
}
Expand All @@ -31,17 +33,27 @@ class cmGlobalBorlandMakefileGenerator : public cmGlobalUnixMakefileGenerator3
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
21 changes: 15 additions & 6 deletions Source/cmGlobalGenerator.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -1782,21 +1782,29 @@ 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);
}

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,
Expand Down Expand Up @@ -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 &&
Expand All @@ -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";
Expand Down
13 changes: 8 additions & 5 deletions Source/cmGlobalGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,17 +147,18 @@ class cmGlobalGenerator
* 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
* that is used by both CTest and TryCompile. If target name is NULL or
* 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,
Expand All @@ -176,9 +177,11 @@ class cmGlobalGenerator
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,
Expand Down
9 changes: 8 additions & 1 deletion Source/cmGlobalGhsMultiGenerator.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down
2 changes: 1 addition & 1 deletion Source/cmGlobalGhsMultiGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class cmGlobalGhsMultiGenerator : public cmGlobalGenerator
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:
Expand Down
26 changes: 26 additions & 0 deletions Source/cmGlobalJOMMakefileGenerator.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
18 changes: 14 additions & 4 deletions Source/cmGlobalJOMMakefileGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include "cmGlobalUnixMakefileGenerator3.h"

#include <iosfwd>

/** \class cmGlobalJOMMakefileGenerator
* \brief Write a JOM makefiles.
*
Expand All @@ -19,7 +21,7 @@ class cmGlobalJOMMakefileGenerator : public cmGlobalUnixMakefileGenerator3
return new cmGlobalGeneratorSimpleFactory<cmGlobalJOMMakefileGenerator>();
}
///! Get the name for the generator.
virtual std::string GetName() const
std::string GetName() const override
{
return cmGlobalJOMMakefileGenerator::GetActualName();
}
Expand All @@ -34,12 +36,20 @@ class cmGlobalJOMMakefileGenerator : public cmGlobalUnixMakefileGenerator3
* 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
37 changes: 37 additions & 0 deletions Source/cmGlobalNMakeMakefileGenerator.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Loading

0 comments on commit f248f8a

Please sign in to comment.