Browse Source

cmGlobalGenerator: Add a class that represent the build command

This refactors a std::vector<std::string> into a class so that
we can extend the features to represent things such as multiple
chained commands in the future.
Robert Maynard 7 years ago
parent
commit
1a45266cb5

+ 1 - 1
Source/cmGlobalBorlandMakefileGenerator.cxx

@@ -54,7 +54,7 @@ void cmGlobalBorlandMakefileGenerator::GetDocumentation(
 }
 
 void cmGlobalBorlandMakefileGenerator::GenerateBuildCommand(
-  std::vector<std::string>& makeCommand, const std::string& makeProgram,
+  GeneratedMakeCommand& 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)

+ 1 - 1
Source/cmGlobalBorlandMakefileGenerator.h

@@ -46,7 +46,7 @@ public:
   bool AllowDeleteOnError() const override { return false; }
 
 protected:
-  void GenerateBuildCommand(std::vector<std::string>& makeCommand,
+  void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
                             const std::string& makeProgram,
                             const std::string& projectName,
                             const std::string& projectDir,

+ 14 - 17
Source/cmGlobalGenerator.cxx

@@ -1751,14 +1751,13 @@ int cmGlobalGenerator::TryCompile(int jobs, const std::string& srcdir,
 }
 
 void cmGlobalGenerator::GenerateBuildCommand(
-  std::vector<std::string>& makeCommand, const std::string& /*unused*/,
+  GeneratedMakeCommand& makeCommand, const std::string& /*unused*/,
   const std::string& /*unused*/, const std::string& /*unused*/,
   const std::string& /*unused*/, const std::string& /*unused*/,
   bool /*unused*/, int /*unused*/, bool /*unused*/,
   std::vector<std::string> const& /*unused*/)
 {
-  makeCommand.emplace_back(
-    "cmGlobalGenerator::GenerateBuildCommand not implemented");
+  makeCommand.add("cmGlobalGenerator::GenerateBuildCommand not implemented");
 }
 
 void cmGlobalGenerator::PrintBuildCommandAdvice(std::ostream& /*os*/,
@@ -1802,31 +1801,29 @@ int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/,
   std::string outputBuffer;
   std::string* outputPtr = &outputBuffer;
 
-  std::vector<std::string> makeCommand;
+  GeneratedMakeCommand makeCommand;
   this->GenerateBuildCommand(makeCommand, makeCommandCSTR, projectName, bindir,
                              target, config, fast, jobs, verbose,
                              nativeOptions);
 
-  // Workaround to convince VCExpress.exe to produce output.
+  // Workaround to convince some commands to produce output.
   if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH &&
-      !makeCommand.empty() &&
-      cmSystemTools::LowerCase(
-        cmSystemTools::GetFilenameName(makeCommand[0])) == "vcexpress.exe") {
+      makeCommand.RequiresOutputForward) {
     outputflag = cmSystemTools::OUTPUT_FORWARD;
   }
 
   // should we do a clean first?
   if (clean) {
-    std::vector<std::string> cleanCommand;
+    GeneratedMakeCommand cleanCommand;
     this->GenerateBuildCommand(cleanCommand, makeCommandCSTR, projectName,
                                bindir, "clean", config, fast, jobs, verbose);
     output += "\nRun Clean Command:";
-    output += cmSystemTools::PrintSingleCommand(cleanCommand);
+    output += cleanCommand.printable();
     output += "\n";
 
-    if (!cmSystemTools::RunSingleCommand(cleanCommand, outputPtr, outputPtr,
-                                         &retVal, nullptr, outputflag,
-                                         timeout)) {
+    if (!cmSystemTools::RunSingleCommand(cleanCommand.PrimaryCommand,
+                                         outputPtr, outputPtr, &retVal,
+                                         nullptr, outputflag, timeout)) {
       cmSystemTools::SetRunCommandHideConsole(hideconsole);
       cmSystemTools::Error("Generator: execution of make clean failed.");
       output += *outputPtr;
@@ -1838,13 +1835,13 @@ int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/,
   }
 
   // now build
-  std::string makeCommandStr = cmSystemTools::PrintSingleCommand(makeCommand);
-  output += "\nRun Build Command:";
+  std::string makeCommandStr = makeCommand.printable();
+  output += "\nRun Build Command(s):";
   output += makeCommandStr;
   output += "\n";
 
-  if (!cmSystemTools::RunSingleCommand(makeCommand, outputPtr, outputPtr,
-                                       &retVal, nullptr, outputflag,
+  if (!cmSystemTools::RunSingleCommand(makeCommand.PrimaryCommand, outputPtr,
+                                       outputPtr, &retVal, nullptr, outputflag,
                                        timeout)) {
     cmSystemTools::SetRunCommandHideConsole(hideconsole);
     cmSystemTools::Error(

+ 53 - 1
Source/cmGlobalGenerator.h

@@ -41,6 +41,54 @@ class cmSourceFile;
 class cmStateDirectory;
 class cmake;
 
+namespace detail {
+inline void AppendStrs(std::vector<std::string>&)
+{
+}
+template <typename T, typename... Ts>
+inline void AppendStrs(std::vector<std::string>& command, T&& s, Ts&&... ts)
+{
+  command.emplace_back(std::forward<T>(s));
+  AppendStrs(command, std::forward<Ts>(ts)...);
+}
+
+struct GeneratedMakeCommand
+{
+  // Add each argument as a separate element to the vector
+  template <typename... T>
+  void add(T&&... args)
+  {
+    // iterate the args and append each one
+    AppendStrs(PrimaryCommand, std::forward<T>(args)...);
+  }
+
+  // Add each value in the iterators as a separate element to the vector
+  void add(std::vector<std::string>::const_iterator start,
+           std::vector<std::string>::const_iterator end)
+  {
+    PrimaryCommand.insert(PrimaryCommand.end(), start, end);
+  }
+
+  std::string printable() const
+  {
+    std::size_t size = PrimaryCommand.size();
+    for (auto&& i : PrimaryCommand) {
+      size += i.size();
+    }
+    std::string buffer;
+    buffer.reserve(size);
+    for (auto&& i : PrimaryCommand) {
+      buffer.append(i);
+      buffer.append(1, ' ');
+    }
+    return buffer;
+  }
+
+  std::vector<std::string> PrimaryCommand;
+  bool RequiresOutputForward = false;
+};
+}
+
 /** \class cmGlobalGenerator
  * \brief Responsible for overseeing the generation process for the entire tree
  *
@@ -182,8 +230,12 @@ public:
   virtual bool Open(const std::string& bindir, const std::string& projectName,
                     bool dryRun);
 
+  struct GeneratedMakeCommand final : public detail::GeneratedMakeCommand
+  {
+  };
+
   virtual void GenerateBuildCommand(
-    std::vector<std::string>& makeCommand, const std::string& makeProgram,
+    GeneratedMakeCommand& 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,

+ 9 - 12
Source/cmGlobalGhsMultiGenerator.cxx

@@ -370,25 +370,23 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
 }
 
 void cmGlobalGhsMultiGenerator::GenerateBuildCommand(
-  std::vector<std::string>& makeCommand, const std::string& makeProgram,
+  GeneratedMakeCommand& 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)
 {
   const char* gbuild =
     this->CMakeInstance->GetCacheDefinition("CMAKE_MAKE_PROGRAM");
-  makeCommand.push_back(
-    this->SelectMakeProgram(makeProgram, (std::string)gbuild));
+  makeCommand.add(this->SelectMakeProgram(makeProgram, (std::string)gbuild));
 
   if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
-    makeCommand.push_back("-parallel");
+    makeCommand.add("-parallel");
     if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
-      makeCommand.push_back(std::to_string(jobs));
+      makeCommand.add(std::to_string(jobs));
     }
   }
 
-  makeCommand.insert(makeCommand.end(), makeOptions.begin(),
-                     makeOptions.end());
+  makeCommand.add(makeOptions.begin(), makeOptions.end());
 
   /* determine which top-project file to use */
   std::string proj = projectName + ".top" + FILE_EXTENSION;
@@ -401,16 +399,15 @@ void cmGlobalGhsMultiGenerator::GenerateBuildCommand(
     }
   }
 
-  makeCommand.push_back("-top");
-  makeCommand.push_back(proj);
+  makeCommand.add("-top", proj);
   if (!targetName.empty()) {
     if (targetName == "clean") {
-      makeCommand.push_back("-clean");
+      makeCommand.add("-clean");
     } else {
       if (targetName.compare(targetName.size() - 4, 4, ".gpj") == 0) {
-        makeCommand.push_back(targetName);
+        makeCommand.add(targetName);
       } else {
-        makeCommand.push_back(targetName + ".gpj");
+        makeCommand.add(targetName + ".gpj");
       }
     }
   }

+ 1 - 1
Source/cmGlobalGhsMultiGenerator.h

@@ -88,7 +88,7 @@ public:
 
 protected:
   void Generate() override;
-  void GenerateBuildCommand(std::vector<std::string>& makeCommand,
+  void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
                             const std::string& makeProgram,
                             const std::string& projectName,
                             const std::string& projectDir,

+ 1 - 1
Source/cmGlobalJOMMakefileGenerator.cxx

@@ -55,7 +55,7 @@ void cmGlobalJOMMakefileGenerator::PrintCompilerAdvice(
 }
 
 void cmGlobalJOMMakefileGenerator::GenerateBuildCommand(
-  std::vector<std::string>& makeCommand, const std::string& makeProgram,
+  GeneratedMakeCommand& 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)

+ 1 - 1
Source/cmGlobalJOMMakefileGenerator.h

@@ -40,7 +40,7 @@ public:
                       bool optional) override;
 
 protected:
-  void GenerateBuildCommand(std::vector<std::string>& makeCommand,
+  void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
                             const std::string& makeProgram,
                             const std::string& projectName,
                             const std::string& projectDir,

+ 1 - 1
Source/cmGlobalNMakeMakefileGenerator.cxx

@@ -55,7 +55,7 @@ void cmGlobalNMakeMakefileGenerator::PrintCompilerAdvice(
 }
 
 void cmGlobalNMakeMakefileGenerator::GenerateBuildCommand(
-  std::vector<std::string>& makeCommand, const std::string& makeProgram,
+  GeneratedMakeCommand& 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)

+ 1 - 1
Source/cmGlobalNMakeMakefileGenerator.h

@@ -45,7 +45,7 @@ public:
                       bool optional) override;
 
 protected:
-  void GenerateBuildCommand(std::vector<std::string>& makeCommand,
+  void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
                             const std::string& makeProgram,
                             const std::string& projectName,
                             const std::string& projectDir,

+ 7 - 10
Source/cmGlobalNinjaGenerator.cxx

@@ -673,31 +673,28 @@ void cmGlobalNinjaGenerator::EnableLanguage(
 // Called by:
 //   cmGlobalGenerator::Build()
 void cmGlobalNinjaGenerator::GenerateBuildCommand(
-  std::vector<std::string>& makeCommand, const std::string& makeProgram,
+  GeneratedMakeCommand& 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)
 {
-  makeCommand.push_back(this->SelectMakeProgram(makeProgram));
+  makeCommand.add(this->SelectMakeProgram(makeProgram));
 
   if (verbose) {
-    makeCommand.emplace_back("-v");
+    makeCommand.add("-v");
   }
 
   if ((jobs != cmake::NO_BUILD_PARALLEL_LEVEL) &&
       (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL)) {
-    makeCommand.emplace_back("-j");
-    makeCommand.push_back(std::to_string(jobs));
+    makeCommand.add("-j", std::to_string(jobs));
   }
 
-  makeCommand.insert(makeCommand.end(), makeOptions.begin(),
-                     makeOptions.end());
+  makeCommand.add(makeOptions.begin(), makeOptions.end());
   if (!targetName.empty()) {
     if (targetName == "clean") {
-      makeCommand.emplace_back("-t");
-      makeCommand.emplace_back("clean");
+      makeCommand.add("-t", "clean");
     } else {
-      makeCommand.push_back(targetName);
+      makeCommand.add(targetName);
     }
   }
 }

+ 1 - 1
Source/cmGlobalNinjaGenerator.h

@@ -202,7 +202,7 @@ public:
   void EnableLanguage(std::vector<std::string> const& languages,
                       cmMakefile* mf, bool optional) override;
 
-  void GenerateBuildCommand(std::vector<std::string>& makeCommand,
+  void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
                             const std::string& makeProgram,
                             const std::string& projectName,
                             const std::string& projectDir,

+ 6 - 7
Source/cmGlobalUnixMakefileGenerator3.cxx

@@ -490,7 +490,7 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
 }
 
 void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
-  std::vector<std::string>& makeCommand, const std::string& makeProgram,
+  GeneratedMakeCommand& 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)
@@ -510,17 +510,16 @@ void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
     mf = mfu.get();
   }
 
-  makeCommand.push_back(this->SelectMakeProgram(makeProgram));
+  makeCommand.add(this->SelectMakeProgram(makeProgram));
 
   if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
-    makeCommand.emplace_back("-j");
+    makeCommand.add("-j");
     if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
-      makeCommand.push_back(std::to_string(jobs));
+      makeCommand.add(std::to_string(jobs));
     }
   }
 
-  makeCommand.insert(makeCommand.end(), makeOptions.begin(),
-                     makeOptions.end());
+  makeCommand.add(makeOptions.begin(), makeOptions.end());
   if (!targetName.empty()) {
     std::string tname = targetName;
     if (fast) {
@@ -530,7 +529,7 @@ void cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
     tname =
       conv.ConvertToRelativePath(mf->GetState()->GetBinaryDirectory(), tname);
     cmSystemTools::ConvertToOutputSlashes(tname);
-    makeCommand.push_back(std::move(tname));
+    makeCommand.add(std::move(tname));
   }
 }
 

+ 1 - 1
Source/cmGlobalUnixMakefileGenerator3.h

@@ -127,7 +127,7 @@ public:
   std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; }
 
   // change the build command for speed
-  void GenerateBuildCommand(std::vector<std::string>& makeCommand,
+  void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
                             const std::string& makeProgram,
                             const std::string& projectName,
                             const std::string& projectDir,

+ 17 - 14
Source/cmGlobalVisualStudio10Generator.cxx

@@ -864,7 +864,7 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
 }
 
 void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
-  std::vector<std::string>& makeCommand, const std::string& makeProgram,
+  GeneratedMakeCommand& 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)
@@ -879,6 +879,10 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
   bool useDevEnv = (makeProgramLower.find("devenv") != std::string::npos ||
                     makeProgramLower.find("vcexpress") != std::string::npos);
 
+  // Workaround to convince VCExpress.exe to produce output.
+  makeCommand.RequiresOutputForward =
+    (makeProgramLower.find("vcexpress") != std::string::npos);
+
   // MSBuild is preferred (and required for VS Express), but if the .sln has
   // an Intel Fortran .vfproj then we have to use devenv. Parse it to find out.
   cmSlnData slnData;
@@ -912,7 +916,7 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
     return;
   }
 
-  makeCommand.push_back(makeProgramSelected);
+  makeCommand.add(makeProgramSelected);
 
   std::string realTarget = targetName;
   // msbuild.exe CxxOnly.sln /t:Build /p:Configuration=Debug /target:ALL_BUILD
@@ -921,8 +925,8 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
     realTarget = "ALL_BUILD";
   }
   if (realTarget == "clean") {
-    makeCommand.push_back(std::string(projectName) + ".sln");
-    makeCommand.push_back("/t:Clean");
+    makeCommand.add(std::string(projectName) + ".sln");
+    makeCommand.add("/t:Clean");
   } else {
     std::string targetProject(realTarget);
     targetProject += ".vcxproj";
@@ -934,7 +938,7 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
         cmSystemTools::ConvertToUnixSlashes(targetProject);
       }
     }
-    makeCommand.push_back(targetProject);
+    makeCommand.add(std::move(targetProject));
   }
   std::string configArg = "/p:Configuration=";
   if (!config.empty()) {
@@ -942,23 +946,22 @@ void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
   } else {
     configArg += "Debug";
   }
-  makeCommand.push_back(configArg);
-  makeCommand.push_back("/p:Platform=" + this->GetPlatformName());
-  makeCommand.push_back(std::string("/p:VisualStudioVersion=") +
-                        this->GetIDEVersion());
+  makeCommand.add(configArg);
+  makeCommand.add(std::string("/p:Platform=") + this->GetPlatformName());
+  makeCommand.add(std::string("/p:VisualStudioVersion=") +
+                  this->GetIDEVersion());
 
   if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
     if (jobs == cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
-      makeCommand.push_back("/m");
+      makeCommand.add("/m");
     } else {
-      makeCommand.push_back(std::string("/m:") + std::to_string(jobs));
+      makeCommand.add(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.add("/p:CL_MPCount=1");
   }
 
-  makeCommand.insert(makeCommand.end(), makeOptions.begin(),
-                     makeOptions.end());
+  makeCommand.add(makeOptions.begin(), makeOptions.end());
 }
 
 bool cmGlobalVisualStudio10Generator::Find64BitTools(cmMakefile* mf)

+ 1 - 1
Source/cmGlobalVisualStudio10Generator.h

@@ -22,7 +22,7 @@ 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,
+  void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
                             const std::string& makeProgram,
                             const std::string& projectName,
                             const std::string& projectDir,

+ 12 - 22
Source/cmGlobalVisualStudio7Generator.cxx

@@ -191,7 +191,7 @@ const char* cmGlobalVisualStudio7Generator::ExternalProjectType(
   return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942";
 }
 void cmGlobalVisualStudio7Generator::GenerateBuildCommand(
-  std::vector<std::string>& makeCommand, const std::string& makeProgram,
+  GeneratedMakeCommand& 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)
@@ -209,35 +209,25 @@ void cmGlobalVisualStudio7Generator::GenerateBuildCommand(
     makeProgramSelected = this->GetDevEnvCommand();
   }
 
-  makeCommand.push_back(makeProgramSelected);
+  // Workaround to convince VCExpress.exe to produce output.
+  makeCommand.RequiresOutputForward =
+    (makeProgramLower.find("vcexpress") != std::string::npos);
 
-  makeCommand.push_back(std::string(projectName) + ".sln");
+  makeCommand.add(makeProgramSelected);
+
+  makeCommand.add(std::string(projectName) + ".sln");
   std::string realTarget = targetName;
   bool clean = false;
   if (realTarget == "clean") {
     clean = true;
     realTarget = "ALL_BUILD";
   }
-  if (clean) {
-    makeCommand.push_back("/clean");
-  } else {
-    makeCommand.push_back("/build");
-  }
-
-  if (!config.empty()) {
-    makeCommand.push_back(config);
-  } else {
-    makeCommand.push_back("Debug");
-  }
-  makeCommand.push_back("/project");
 
-  if (!realTarget.empty()) {
-    makeCommand.push_back(realTarget);
-  } else {
-    makeCommand.push_back("ALL_BUILD");
-  }
-  makeCommand.insert(makeCommand.end(), makeOptions.begin(),
-                     makeOptions.end());
+  makeCommand.add((clean ? "/clean" : "/build"));
+  makeCommand.add((config.empty() ? "Debug" : config));
+  makeCommand.add("/project");
+  makeCommand.add((realTarget.empty() ? "ALL_BUILD" : realTarget));
+  makeCommand.add(makeOptions.begin(), makeOptions.end());
 }
 
 ///! Create a local generator appropriate to this Global Generator

+ 1 - 1
Source/cmGlobalVisualStudio7Generator.h

@@ -52,7 +52,7 @@ 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,
+  void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
                             const std::string& makeProgram,
                             const std::string& projectName,
                             const std::string& projectDir,

+ 1 - 1
Source/cmGlobalWatcomWMakeGenerator.cxx

@@ -51,7 +51,7 @@ void cmGlobalWatcomWMakeGenerator::GetDocumentation(
 }
 
 void cmGlobalWatcomWMakeGenerator::GenerateBuildCommand(
-  std::vector<std::string>& makeCommand, const std::string& makeProgram,
+  GeneratedMakeCommand& 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)

+ 1 - 1
Source/cmGlobalWatcomWMakeGenerator.h

@@ -50,7 +50,7 @@ public:
   bool AllowDeleteOnError() const override { return false; }
 
 protected:
-  void GenerateBuildCommand(std::vector<std::string>& makeCommand,
+  void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
                             const std::string& makeProgram,
                             const std::string& projectName,
                             const std::string& projectDir,

+ 11 - 21
Source/cmGlobalXCodeGenerator.cxx

@@ -339,20 +339,20 @@ bool cmGlobalXCodeGenerator::Open(const std::string& bindir,
 }
 
 void cmGlobalXCodeGenerator::GenerateBuildCommand(
-  std::vector<std::string>& makeCommand, const std::string& makeProgram,
+  GeneratedMakeCommand& 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)
 {
   // now build the test
-  makeCommand.emplace_back(
+  makeCommand.add(
     this->SelectMakeProgram(makeProgram, this->GetXcodeBuildCommand()));
 
-  makeCommand.emplace_back("-project");
+  makeCommand.add("-project");
   std::string projectArg = projectName;
   projectArg += ".xcode";
   projectArg += "proj";
-  makeCommand.emplace_back(projectArg);
+  makeCommand.add(projectArg);
 
   bool clean = false;
   std::string realTarget = targetName;
@@ -360,29 +360,19 @@ void cmGlobalXCodeGenerator::GenerateBuildCommand(
     clean = true;
     realTarget = "ALL_BUILD";
   }
-  if (clean) {
-    makeCommand.emplace_back("clean");
-  } else {
-    makeCommand.emplace_back("build");
-  }
-  makeCommand.emplace_back("-target");
-  if (!realTarget.empty()) {
-    makeCommand.emplace_back(realTarget);
-  } else {
-    makeCommand.emplace_back("ALL_BUILD");
-  }
-  makeCommand.emplace_back("-configuration");
-  makeCommand.emplace_back(!config.empty() ? config : "Debug");
+
+  makeCommand.add((clean ? "clean" : "build"));
+  makeCommand.add("-target", (realTarget.empty() ? "ALL_BUILD" : realTarget));
+  makeCommand.add("-configuration", (config.empty() ? "Debug" : config));
 
   if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
-    makeCommand.emplace_back("-jobs");
+    makeCommand.add("-jobs");
     if (jobs != cmake::DEFAULT_BUILD_PARALLEL_LEVEL) {
-      makeCommand.emplace_back(std::to_string(jobs));
+      makeCommand.add(std::to_string(jobs));
     }
   }
 
-  makeCommand.insert(makeCommand.end(), makeOptions.begin(),
-                     makeOptions.end());
+  makeCommand.add(makeOptions.begin(), makeOptions.end());
 }
 
 ///! Create a local generator appropriate to this Global Generator

+ 1 - 1
Source/cmGlobalXCodeGenerator.h

@@ -66,7 +66,7 @@ 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,
+  void GenerateBuildCommand(GeneratedMakeCommand& makeCommand,
                             const std::string& makeProgram,
                             const std::string& projectName,
                             const std::string& projectDir,