From fc2ac460435df289149e4faaf494e6b287071a8c Mon Sep 17 00:00:00 2001
From: friendlyanon <friendlyanon_@hotmail.com>
Date: Sat, 1 May 2021 16:10:21 +0200
Subject: build_command: Add the PARALLEL_LEVEL argument

Issue: #19712
---
 Help/command/build_command.rst                           | 16 +++++++++++-----
 .../dev/generate-cmake-build-command-parallel.rst        |  4 ++++
 Source/cmBuildCommand.cxx                                | 11 +++++++++--
 Tests/RunCMake/build_command/ParallelLevel.cmake         |  5 +++++
 Tests/RunCMake/build_command/RunCMakeTest.cmake          |  2 ++
 5 files changed, 31 insertions(+), 7 deletions(-)
 create mode 100644 Help/release/dev/generate-cmake-build-command-parallel.rst
 create mode 100644 Tests/RunCMake/build_command/ParallelLevel.cmake

diff --git a/Help/command/build_command.rst b/Help/command/build_command.rst
index 6659005..a03979d 100644
--- a/Help/command/build_command.rst
+++ b/Help/command/build_command.rst
@@ -8,23 +8,29 @@ This is mainly intended for internal use by the :module:`CTest` module.
 
   build_command(<variable>
                 [CONFIGURATION <config>]
+                [PARALLEL_LEVEL <parallel>]
                 [TARGET <target>]
                 [PROJECT_NAME <projname>] # legacy, causes warning
                )
 
 Sets the given ``<variable>`` to a command-line string of the form::
 
- <cmake> --build . [--config <config>] [--target <target>...] [-- -i]
+ <cmake> --build . [--config <config>] [--parallel <parallel>] [--target <target>...] [-- -i]
 
 where ``<cmake>`` is the location of the :manual:`cmake(1)` command-line
-tool, and ``<config>`` and ``<target>`` are the values provided to the
-``CONFIGURATION`` and ``TARGET`` options, if any.  The trailing ``-- -i``
-option is added for :ref:`Makefile Generators` if policy :policy:`CMP0061`
-is not set to ``NEW``.
+tool, and ``<config>``, ``<parallel>`` and ``<target>`` are the values
+provided to the ``CONFIGURATION``, ``PARALLEL_LEVEL`` and ``TARGET``
+options, if any.  The trailing ``-- -i`` option is added for
+:ref:`Makefile Generators` if policy :policy:`CMP0061` is not set to
+``NEW``.
 
 When invoked, this ``cmake --build`` command line will launch the
 underlying build system tool.
 
+.. versionadded:: 3.21
+  The ``PARALLEL_LEVEL`` argument can be used to set the ``--parallel``
+  flag.
+
 .. code-block:: cmake
 
   build_command(<cachevariable> <makecommand>)
diff --git a/Help/release/dev/generate-cmake-build-command-parallel.rst b/Help/release/dev/generate-cmake-build-command-parallel.rst
new file mode 100644
index 0000000..8d3b7d7
--- /dev/null
+++ b/Help/release/dev/generate-cmake-build-command-parallel.rst
@@ -0,0 +1,4 @@
+generate-cmake-build-command-parallel
+-------------------------------------
+
+* The :command:`build_command` command gained a ``PARALLEL_LEVEL`` option.
diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx
index 4830343..56b080a 100644
--- a/Source/cmBuildCommand.cxx
+++ b/Source/cmBuildCommand.cxx
@@ -28,12 +28,14 @@ bool MainSignature(std::vector<std::string> const& args,
   std::string configuration;
   std::string project_name;
   std::string target;
+  std::string parallel;
   enum Doing
   {
     DoingNone,
     DoingConfiguration,
     DoingProjectName,
-    DoingTarget
+    DoingTarget,
+    DoingParallel
   };
   Doing doing = DoingNone;
   for (unsigned int i = 1; i < args.size(); ++i) {
@@ -43,6 +45,8 @@ bool MainSignature(std::vector<std::string> const& args,
       doing = DoingProjectName;
     } else if (args[i] == "TARGET") {
       doing = DoingTarget;
+    } else if (args[i] == "PARALLEL_LEVEL") {
+      doing = DoingParallel;
     } else if (doing == DoingConfiguration) {
       doing = DoingNone;
       configuration = args[i];
@@ -52,6 +56,9 @@ bool MainSignature(std::vector<std::string> const& args,
     } else if (doing == DoingTarget) {
       doing = DoingNone;
       target = args[i];
+    } else if (doing == DoingParallel) {
+      doing = DoingNone;
+      parallel = args[i];
     } else {
       status.SetError(cmStrCat("unknown argument \"", args[i], "\""));
       return false;
@@ -77,7 +84,7 @@ bool MainSignature(std::vector<std::string> const& args,
   }
 
   std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand(
-    target, configuration, "", "", mf.IgnoreErrorsCMP0061());
+    target, configuration, parallel, "", mf.IgnoreErrorsCMP0061());
 
   mf.AddDefinition(variable, makecommand);
 
diff --git a/Tests/RunCMake/build_command/ParallelLevel.cmake b/Tests/RunCMake/build_command/ParallelLevel.cmake
new file mode 100644
index 0000000..1d1e525
--- /dev/null
+++ b/Tests/RunCMake/build_command/ParallelLevel.cmake
@@ -0,0 +1,5 @@
+cmake_policy(SET CMP0061 NEW)
+build_command(cmd PARALLEL_LEVEL 1)
+if(NOT cmd MATCHES [[ --parallel "1"]])
+  message(FATAL_ERROR "Cannot find the --parallel flag")
+endif()
diff --git a/Tests/RunCMake/build_command/RunCMakeTest.cmake b/Tests/RunCMake/build_command/RunCMakeTest.cmake
index c3bef4c..030db0b 100644
--- a/Tests/RunCMake/build_command/RunCMakeTest.cmake
+++ b/Tests/RunCMake/build_command/RunCMakeTest.cmake
@@ -14,3 +14,5 @@ if(RunCMake_GENERATOR MATCHES "Make")
 else()
   run_cmake(CMP0061-OLD-other)
 endif()
+
+run_cmake(ParallelLevel)
-- 
cgit v0.12