Browse Source

cmGlobalGenerator: Cleanup GenerateBuildCommand API

All cmGlobalGenerator::GenerateBuildCommand call sites that need to
produce a string now generate "cmake --build" commands.  The remaining
call sites immediately pass the result to cmSystemTools::RunSingleCommand.
Avoid the intermediate string and argument parsing by directly producing a
vector of strings.  Also drop the ignoreErrors argument because no call
sites remain that use it.
Brad King 12 years ago
parent
commit
8904d1410b

+ 10 - 8
Source/CPack/cmCPackGenerator.cxx

@@ -637,19 +637,21 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
         globalGenerator->FindMakeProgram(this->MakefileMap);
         const char* cmakeMakeProgram
           = this->MakefileMap->GetDefinition("CMAKE_MAKE_PROGRAM");
-        std::string buildCommand
-          = globalGenerator->GenerateBuildCommand(cmakeMakeProgram,
-            installProjectName.c_str(), 0, 0,
+        std::vector<std::string> buildCommand;
+        globalGenerator->GenerateBuildCommand(buildCommand, cmakeMakeProgram,
+            installProjectName.c_str(), installDirectory.c_str(),
             globalGenerator->GetPreinstallTargetName(),
-            buildConfig, false, false);
+            buildConfig, false);
+        std::string buildCommandStr =
+          cmSystemTools::PrintSingleCommand(buildCommand);
         cmCPackLogger(cmCPackLog::LOG_DEBUG,
-          "- Install command: " << buildCommand << std::endl);
+          "- Install command: " << buildCommandStr << std::endl);
         cmCPackLogger(cmCPackLog::LOG_OUTPUT,
           "- Run preinstall target for: " << installProjectName << std::endl);
         std::string output;
         int retVal = 1;
         bool resB =
-          cmSystemTools::RunSingleCommand(buildCommand.c_str(),
+          cmSystemTools::RunSingleCommand(buildCommand,
                                           &output,
                                           &retVal,
                                           installDirectory.c_str(),
@@ -659,12 +661,12 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
           std::string tmpFile = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
           tmpFile += "/PreinstallOutput.log";
           cmGeneratedFileStream ofs(tmpFile.c_str());
-          ofs << "# Run command: " << buildCommand.c_str() << std::endl
+          ofs << "# Run command: " << buildCommandStr.c_str() << std::endl
             << "# Directory: " << installDirectory.c_str() << std::endl
             << "# Output:" << std::endl
             << output.c_str() << std::endl;
           cmCPackLogger(cmCPackLog::LOG_ERROR,
-            "Problem running install command: " << buildCommand.c_str()
+            "Problem running install command: " << buildCommandStr.c_str()
             << std::endl
             << "Please check " << tmpFile.c_str() << " for errors"
             << std::endl);

+ 18 - 28
Source/cmGlobalGenerator.cxx

@@ -1574,13 +1574,12 @@ int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir,
                      this->TryCompileTimeout);
 }
 
-std::string cmGlobalGenerator
-::GenerateBuildCommand(const char*, const char*,
-                       const char*, const char*,
-                       const char*, const char*,
-                       bool, bool)
+void cmGlobalGenerator::GenerateBuildCommand(
+  std::vector<std::string>& makeCommand, const char*, const char*, const char*,
+  const char*, const char*, bool, std::vector<std::string> const&)
 {
-  return "cmGlobalGenerator::GenerateBuildCommand not implemented";
+  makeCommand.push_back(
+    "cmGlobalGenerator::GenerateBuildCommand not implemented");
 }
 
 int cmGlobalGenerator::Build(
@@ -1592,7 +1591,6 @@ int cmGlobalGenerator::Build(
   bool clean, bool fast,
   double timeout,
   cmSystemTools::OutputOption outputflag,
-  const char* extraOptions,
   std::vector<std::string> const& nativeOptions)
 {
   /**
@@ -1620,17 +1618,17 @@ int cmGlobalGenerator::Build(
   // should we do a clean first?
   if (clean)
     {
-    std::string cleanCommand =
-      this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir,
-      0, "clean", config, false, fast);
+    std::vector<std::string> cleanCommand;
+    this->GenerateBuildCommand(cleanCommand, makeCommandCSTR, projectName,
+                               bindir, "clean", config, fast);
     if(output)
       {
       *output += "\nRun Clean Command:";
-      *output += cleanCommand;
+      *output += cmSystemTools::PrintSingleCommand(cleanCommand);
       *output += "\n";
       }
 
-    if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), outputPtr,
+    if (!cmSystemTools::RunSingleCommand(cleanCommand, outputPtr,
                                          &retVal, 0, outputflag, timeout))
       {
       cmSystemTools::SetRunCommandHideConsole(hideconsole);
@@ -1652,37 +1650,29 @@ int cmGlobalGenerator::Build(
     }
 
   // now build
-  std::string makeCommand =
-    this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir,
-                               extraOptions, target,
-                               config, false, fast);
+  std::vector<std::string> makeCommand;
+  this->GenerateBuildCommand(makeCommand, makeCommandCSTR, projectName,
+                             bindir, target, config, fast, nativeOptions);
+  std::string makeCommandStr = cmSystemTools::PrintSingleCommand(makeCommand);
   if(output)
     {
     *output += "\nRun Build Command:";
-    *output += makeCommand;
+    *output += makeCommandStr;
     *output += "\n";
     }
 
-  std::vector<cmStdString> command =
-    cmSystemTools::ParseArguments(makeCommand.c_str());
-  for(std::vector<std::string>::const_iterator ni = nativeOptions.begin();
-      ni != nativeOptions.end(); ++ni)
-    {
-    command.push_back(*ni);
-    }
-
-  if (!cmSystemTools::RunSingleCommand(command, outputPtr,
+  if (!cmSystemTools::RunSingleCommand(makeCommand, outputPtr,
                                        &retVal, 0, outputflag, timeout))
     {
     cmSystemTools::SetRunCommandHideConsole(hideconsole);
     cmSystemTools::Error
       ("Generator: execution of make failed. Make command was: ",
-       makeCommand.c_str());
+       makeCommandStr.c_str());
     if (output)
       {
       *output += *outputPtr;
       *output += "\nGenerator: execution of make failed. Make command was: "
-        + makeCommand + "\n";
+        + makeCommandStr + "\n";
       }
 
     // return to the original directory

+ 5 - 5
Source/cmGlobalGenerator.h

@@ -123,16 +123,16 @@ public:
             bool clean, bool fast,
             double timeout,
             cmSystemTools::OutputOption outputflag=cmSystemTools::OUTPUT_NONE,
-            const char* extraOptions = 0,
             std::vector<std::string> const& nativeOptions =
             std::vector<std::string>());
 
-  virtual std::string GenerateBuildCommand(
+  virtual void GenerateBuildCommand(
+    std::vector<std::string>& makeCommand,
     const char* makeProgram,
     const char *projectName, const char *projectDir,
-    const char* additionalOptions,
-    const char *targetName, const char* config,
-    bool ignoreErrors, bool fast);
+    const char *targetName, const char* config, bool fast,
+    std::vector<std::string> const& makeOptions = std::vector<std::string>()
+    );
 
   /** Generate a "cmake --build" call for a given target and config.  */
   std::string GenerateCMakeBuildCommand(const char* target,

+ 16 - 31
Source/cmGlobalNinjaGenerator.cxx

@@ -549,47 +549,32 @@ bool cmGlobalNinjaGenerator::UsingMinGW = false;
 //   cmGlobalXCodeGenerator
 // Called by:
 //   cmGlobalGenerator::Build()
-std::string cmGlobalNinjaGenerator
-::GenerateBuildCommand(const char* makeProgram,
-                       const char* projectName,
-                       const char* projectDir,
-                       const char* additionalOptions,
+void cmGlobalNinjaGenerator
+::GenerateBuildCommand(std::vector<std::string>& makeCommand,
+                       const char* makeProgram,
+                       const char* /*projectName*/,
+                       const char* /*projectDir*/,
                        const char* targetName,
-                       const char* config,
-                       bool ignoreErrors,
-                       bool fast)
+                       const char* /*config*/,
+                       bool /*fast*/,
+                       std::vector<std::string> const& makeOptions)
 {
-  // Project name & dir and config are not used yet.
-  (void)projectName;
-  (void)projectDir;
-  (void)config;
-  // Ninja does not have -i equivalent option yet.
-  (void)ignoreErrors;
-  // We do not handle fast build yet.
-  (void)fast;
-
-  std::string makeCommand =
-    cmSystemTools::ConvertToUnixOutputPath(makeProgram);
-
-  if(additionalOptions)
-    {
-    makeCommand += " ";
-    makeCommand += additionalOptions;
-    }
-  if(targetName)
+  makeCommand.push_back(makeProgram);
+
+  makeCommand.insert(makeCommand.end(),
+                     makeOptions.begin(), makeOptions.end());
+  if(targetName && *targetName)
     {
     if(strcmp(targetName, "clean") == 0)
       {
-      makeCommand += " -t clean";
+      makeCommand.push_back("-t");
+      makeCommand.push_back("clean");
       }
     else
       {
-      makeCommand += " ";
-      makeCommand += targetName;
+      makeCommand.push_back(targetName);
       }
     }
-
-  return makeCommand;
 }
 
 //----------------------------------------------------------------------------

+ 10 - 8
Source/cmGlobalNinjaGenerator.h

@@ -191,14 +191,16 @@ public:
                               bool optional);
 
   /// Overloaded methods. @see cmGlobalGenerator::GenerateBuildCommand()
-  virtual std::string GenerateBuildCommand(const char* makeProgram,
-                                           const char* projectName,
-                                           const char* projectDir,
-                                           const char* additionalOptions,
-                                           const char* targetName,
-                                           const char* config,
-                                           bool ignoreErrors,
-                                           bool fast);
+  virtual void GenerateBuildCommand(
+    std::vector<std::string>& makeCommand,
+    const char* makeProgram,
+    const char* projectName,
+    const char* projectDir,
+    const char* targetName,
+    const char* config,
+    bool fast,
+    std::vector<std::string> const& makeOptions = std::vector<std::string>()
+    );
 
   // Setup target names
   virtual const char* GetAllTargetName()           const { return "all"; }

+ 17 - 29
Source/cmGlobalUnixMakefileGenerator3.cxx

@@ -555,36 +555,27 @@ cmGlobalUnixMakefileGenerator3
   this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", true, true);
 }
 
-
-std::string cmGlobalUnixMakefileGenerator3
-::GenerateBuildCommand(const char* makeProgram, const char *projectName,
-                       const char *projectDir, const char* additionalOptions,
-                       const char *targetName, const char* config,
-                       bool ignoreErrors, bool fast)
+//----------------------------------------------------------------------------
+void cmGlobalUnixMakefileGenerator3
+::GenerateBuildCommand(std::vector<std::string>& makeCommand,
+                       const char* makeProgram,
+                       const char* /*projectName*/,
+                       const char* /*projectDir*/,
+                       const char* targetName,
+                       const char* /*config*/,
+                       bool fast,
+                       std::vector<std::string> const& makeOptions)
 {
-  // Project name & dir and config are not used yet.
-  (void)projectName;
-  (void)projectDir;
-  (void)config;
-
-  std::string makeCommand =
-    cmSystemTools::ConvertToUnixOutputPath(makeProgram);
+  makeCommand.push_back(makeProgram);
 
   // Since we have full control over the invocation of nmake, let us
   // make it quiet.
   if ( strcmp(this->GetName(), "NMake Makefiles") == 0 )
     {
-    makeCommand += " /NOLOGO ";
-    }
-  if ( ignoreErrors )
-    {
-    makeCommand += " -i";
-    }
-  if ( additionalOptions )
-    {
-    makeCommand += " ";
-    makeCommand += additionalOptions;
+    makeCommand.push_back("/NOLOGO");
     }
+  makeCommand.insert(makeCommand.end(),
+                     makeOptions.begin(), makeOptions.end());
   if ( targetName && strlen(targetName))
     {
     cmLocalUnixMakefileGenerator3 *lg;
@@ -605,22 +596,19 @@ std::string cmGlobalUnixMakefileGenerator3
       lg->GetMakefile()->MakeStartDirectoriesCurrent();
       }
 
-    makeCommand += " \"";
     std::string tname = targetName;
     if(fast)
       {
       tname += "/fast";
       }
-    tname = lg->Convert(tname.c_str(),cmLocalGenerator::HOME_OUTPUT,
-                        cmLocalGenerator::MAKEFILE);
-    makeCommand += tname.c_str();
-    makeCommand += "\"";
+    tname = lg->Convert(tname.c_str(),cmLocalGenerator::HOME_OUTPUT);
+    cmSystemTools::ConvertToOutputSlashes(tname);
+    makeCommand.push_back(tname);
     if (!this->LocalGenerators.size())
       {
       delete lg;
       }
     }
-  return makeCommand;
 }
 
 //----------------------------------------------------------------------------

+ 10 - 6
Source/cmGlobalUnixMakefileGenerator3.h

@@ -107,12 +107,16 @@ public:
   std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; }
 
   // change the build command for speed
-  virtual std::string GenerateBuildCommand
-  (const char* makeProgram,
-   const char *projectName, const char *projectDir,
-   const char* additionalOptions,
-   const char *targetName,
-   const char* config, bool ignoreErrors, bool fast);
+  virtual void GenerateBuildCommand(
+    std::vector<std::string>& makeCommand,
+    const char* makeProgram,
+    const char* projectName,
+    const char* projectDir,
+    const char* targetName,
+    const char* config,
+    bool fast,
+    std::vector<std::string> const& makeOptions = std::vector<std::string>()
+    );
 
   /** Record per-target progress information.  */
   void RecordTargetProgress(cmMakefileTargetGenerator* tg);

+ 27 - 38
Source/cmGlobalVisualStudio10Generator.cxx

@@ -256,49 +256,43 @@ std::string cmGlobalVisualStudio10Generator::GetUserMacrosRegKeyBase()
 }
 
 
-std::string cmGlobalVisualStudio10Generator
-::GenerateBuildCommand(const char* makeProgram,
-                       const char *projectName, const char *projectDir,
-                       const char* additionalOptions, const char *targetName,
-                       const char* config, bool ignoreErrors, bool fast)
+void cmGlobalVisualStudio10Generator::GenerateBuildCommand(
+  std::vector<std::string>& makeCommand,
+  const char* makeProgram,
+  const char* projectName,
+  const char* projectDir,
+  const char* targetName,
+  const char* config,
+  bool fast,
+  std::vector<std::string> const& makeOptions)
 {
   // now build the test
-  std::string makeCommand
-    = cmSystemTools::ConvertToOutputPath(makeProgram);
-  std::string lowerCaseCommand = makeCommand;
+  std::string lowerCaseCommand = makeProgram;
   cmSystemTools::LowerCase(lowerCaseCommand);
 
   // If makeProgram is devenv, parent class knows how to generate command:
   if (lowerCaseCommand.find("devenv") != std::string::npos ||
       lowerCaseCommand.find("VCExpress") != std::string::npos)
     {
-    return cmGlobalVisualStudio7Generator::GenerateBuildCommand(makeProgram,
-      projectName, projectDir, additionalOptions, targetName, config,
-      ignoreErrors, fast);
+    cmGlobalVisualStudio7Generator::GenerateBuildCommand(
+      makeCommand, makeProgram, projectName, projectDir,
+      targetName, config, fast, makeOptions);
+    return;
     }
 
   // Otherwise, assume MSBuild command line, and construct accordingly.
 
-  // if there are spaces in the makeCommand, assume a full path
-  // and convert it to a path with no spaces in it as the
-  // RunSingleCommand does not like spaces
-  if(makeCommand.find(' ') != std::string::npos)
-    {
-    cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand);
-    }
+  makeCommand.push_back(makeProgram);
+
   // msbuild.exe CxxOnly.sln /t:Build /p:Configuration=Debug /target:ALL_BUILD
   if(!targetName || strlen(targetName) == 0)
     {
     targetName = "ALL_BUILD";
     }
-  bool clean = false;
   if ( targetName && strcmp(targetName, "clean") == 0 )
     {
-    clean = true;
-    makeCommand += " ";
-    makeCommand += projectName;
-    makeCommand += ".sln ";
-    makeCommand += "/t:Clean ";
+    makeCommand.push_back(std::string(projectName)+".sln");
+    makeCommand.push_back("/t:Clean");
     }
   else
     {
@@ -331,27 +325,22 @@ std::string cmGlobalVisualStudio10Generator
           }
         }
       }
-    makeCommand += " ";
-    makeCommand += targetProject;
-    makeCommand += " ";
+    makeCommand.push_back(targetProject);
     }
-  makeCommand += "/p:Configuration=";
+  std::string configArg = "/p:Configuration=";
   if(config && strlen(config))
     {
-    makeCommand += config;
+    configArg += config;
     }
   else
     {
-    makeCommand += "Debug";
-    }
-  makeCommand += " /p:VisualStudioVersion=";
-  makeCommand += this->GetIDEVersion();
-  if ( additionalOptions )
-    {
-    makeCommand += " ";
-    makeCommand += additionalOptions;
+    configArg += "Debug";
     }
-  return makeCommand;
+  makeCommand.push_back(configArg);
+  makeCommand.push_back(std::string("/p:VisualStudioVersion=")+
+                        this->GetIDEVersion());
+  makeCommand.insert(makeCommand.end(),
+                     makeOptions.begin(), makeOptions.end());
 }
 
 //----------------------------------------------------------------------------

+ 10 - 5
Source/cmGlobalVisualStudio10Generator.h

@@ -32,11 +32,16 @@ public:
 
   virtual bool SetGeneratorToolset(std::string const& ts);
 
-  virtual std::string
-  GenerateBuildCommand(const char* makeProgram,
-                       const char *projectName, const char *projectDir,
-                       const char* additionalOptions, const char *targetName,
-                       const char* config, bool ignoreErrors, bool);
+  virtual void GenerateBuildCommand(
+    std::vector<std::string>& makeCommand,
+    const char* makeProgram,
+    const char* projectName,
+    const char* projectDir,
+    const char* targetName,
+    const char* config,
+    bool fast,
+    std::vector<std::string> const& makeOptions = std::vector<std::string>()
+    );
 
   virtual void AddPlatformDefinitions(cmMakefile* mf);
 

+ 29 - 43
Source/cmGlobalVisualStudio6Generator.cxx

@@ -77,52 +77,41 @@ void cmGlobalVisualStudio6Generator::GenerateConfigurations(cmMakefile* mf)
     }
 }
 
-std::string cmGlobalVisualStudio6Generator
-::GenerateBuildCommand(const char* makeProgram,
-                       const char *projectName,
-                       const char *projectDir,
-                       const char* additionalOptions,
-                       const char *targetName,
-                       const char* config,
-                       bool ignoreErrors,
-                       bool)
+void
+cmGlobalVisualStudio6Generator::GenerateBuildCommand(
+  std::vector<std::string>& makeCommand,
+  const char* makeProgram,
+  const char* projectName,
+  const char* /*projectDir*/,
+  const char* targetName,
+  const char* config,
+  bool /*fast*/,
+  std::vector<std::string> const& makeOptions
+  )
 {
-  // Visual studio 6 doesn't need project dir
-  (void) projectDir;
-  // Ingoring errors is not implemented in visual studio 6
-  (void) ignoreErrors;
-
   // now build the test
   std::vector<std::string> mp;
   mp.push_back("[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio"
                "\\6.0\\Setup;VsCommonDir]/MSDev98/Bin");
   cmSystemTools::ExpandRegistryValues(mp[0]);
   std::string originalCommand = makeProgram;
-  std::string makeCommand =
+  std::string makeCommandFound =
     cmSystemTools::FindProgram(makeProgram, mp);
-  if(makeCommand.size() == 0)
+  if(makeCommandFound.size() == 0)
     {
     std::string e = "Generator cannot find Visual Studio 6 msdev program \"";
     e += originalCommand;
     e += "\" specified by CMAKE_MAKE_PROGRAM cache entry.  ";
     e += "Please fix the setting.";
     cmSystemTools::Error(e.c_str());
-    return "";
+    return;
     }
-  makeCommand = cmSystemTools::ConvertToOutputPath(makeCommand.c_str());
 
-  // if there are spaces in the makeCommand, assume a full path
-  // and convert it to a path with no spaces in it as the
-  // RunSingleCommand does not like spaces
-#if defined(_WIN32) && !defined(__CYGWIN__)
-  if(makeCommand.find(' ') != std::string::npos)
-    {
-    cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand);
-    }
-#endif
-  makeCommand += " ";
-  makeCommand += projectName;
-  makeCommand += ".dsw /MAKE \"";
+  makeCommand.push_back(makeCommandFound);
+
+  makeCommand.push_back(std::string(projectName)+".dsw");
+  makeCommand.push_back("/MAKE");
+  std::string targetArg;
   bool clean = false;
   if ( targetName && strcmp(targetName, "clean") == 0 )
     {
@@ -131,35 +120,32 @@ std::string cmGlobalVisualStudio6Generator
     }
   if (targetName && strlen(targetName))
     {
-    makeCommand += targetName;
+    targetArg += targetName;
     }
   else
     {
-    makeCommand += "ALL_BUILD";
+    targetArg += "ALL_BUILD";
     }
-  makeCommand += " - ";
+  targetArg += " - ";
   if(config && strlen(config))
     {
-    makeCommand += config;
+    targetArg += config;
     }
   else
     {
-    makeCommand += "Debug";
+    targetArg += "Debug";
     }
+  makeCommand.push_back(targetArg);
   if(clean)
     {
-    makeCommand += "\" /CLEAN";
+    makeCommand.push_back("/CLEAN");
     }
   else
     {
-    makeCommand += "\" /BUILD";
-    }
-  if ( additionalOptions )
-    {
-    makeCommand += " ";
-    makeCommand += additionalOptions;
+    makeCommand.push_back("/BUILD");
     }
-  return makeCommand;
+  makeCommand.insert(makeCommand.end(),
+                     makeOptions.begin(), makeOptions.end());
 }
 
 ///! Create a local generator appropriate to this Global Generator

+ 10 - 8
Source/cmGlobalVisualStudio6Generator.h

@@ -52,14 +52,16 @@ public:
    * Try running cmake and building a file. This is used for dynalically
    * loaded commands, not as part of the usual build process.
    */
-  virtual std::string GenerateBuildCommand(const char* makeProgram,
-                                           const char *projectName,
-                                           const char *projectDir,
-                                           const char* additionalOptions,
-                                           const char *targetName,
-                                           const char* config,
-                                           bool ignoreErrors,
-                                           bool fast);
+  virtual void GenerateBuildCommand(
+    std::vector<std::string>& makeCommand,
+    const char* makeProgram,
+    const char* projectName,
+    const char* projectDir,
+    const char* targetName,
+    const char* config,
+    bool fast,
+    std::vector<std::string> const& makeOptions = std::vector<std::string>()
+    );
 
   /**
    * Generate the all required files for building this project/tree. This

+ 22 - 42
Source/cmGlobalVisualStudio7Generator.cxx

@@ -110,35 +110,19 @@ void cmGlobalVisualStudio7Generator
 
 }
 
-std::string cmGlobalVisualStudio7Generator
-::GenerateBuildCommand(const char* makeProgram,
-                       const char *projectName, const char *projectDir,
-                       const char* additionalOptions, const char *targetName,
-                       const char* config, bool ignoreErrors, bool)
-{
-  // Visual studio 7 doesn't need project dir
-  (void) projectDir;
-  // Ingoring errors is not implemented in visual studio 6
-  (void) ignoreErrors;
-
-  // now build the test
-  std::string makeCommand =
-    cmSystemTools::ConvertToOutputPath(makeProgram);
-  std::string lowerCaseCommand = makeCommand;
-  cmSystemTools::LowerCase(lowerCaseCommand);
-
-  // if there are spaces in the makeCommand, assume a full path
-  // and convert it to a path with no spaces in it as the
-  // RunSingleCommand does not like spaces
-#if defined(_WIN32) && !defined(__CYGWIN__)
-  if(makeCommand.find(' ') != std::string::npos)
-    {
-    cmSystemTools::GetShortPath(makeCommand.c_str(), makeCommand);
-    }
-#endif
-  makeCommand += " ";
-  makeCommand += projectName;
-  makeCommand += ".sln ";
+void cmGlobalVisualStudio7Generator::GenerateBuildCommand(
+  std::vector<std::string>& makeCommand,
+  const char* makeProgram,
+  const char* projectName,
+  const char* /*projectDir*/,
+  const char* targetName,
+  const char* config,
+  bool /*fast*/,
+  std::vector<std::string> const& makeOptions)
+{
+  makeCommand.push_back(makeProgram);
+
+  makeCommand.push_back(std::string(projectName) + ".sln");
   bool clean = false;
   if ( targetName && strcmp(targetName, "clean") == 0 )
     {
@@ -147,37 +131,33 @@ std::string cmGlobalVisualStudio7Generator
     }
   if(clean)
     {
-    makeCommand += "/clean ";
+    makeCommand.push_back("/clean");
     }
   else
     {
-    makeCommand += "/build ";
+    makeCommand.push_back("/build");
     }
 
   if(config && strlen(config))
     {
-    makeCommand += config;
+    makeCommand.push_back(config);
     }
   else
     {
-    makeCommand += "Debug";
+    makeCommand.push_back("Debug");
     }
-  makeCommand += " /project ";
+  makeCommand.push_back("/project");
 
   if (targetName && strlen(targetName))
     {
-    makeCommand += targetName;
+    makeCommand.push_back(targetName);
     }
   else
     {
-    makeCommand += "ALL_BUILD";
+    makeCommand.push_back("ALL_BUILD");
     }
-  if ( additionalOptions )
-    {
-    makeCommand += " ";
-    makeCommand += additionalOptions;
-    }
-  return makeCommand;
+  makeCommand.insert(makeCommand.end(),
+                     makeOptions.begin(), makeOptions.end());
 }
 
 ///! Create a local generator appropriate to this Global Generator

+ 10 - 8
Source/cmGlobalVisualStudio7Generator.h

@@ -60,14 +60,16 @@ public:
    * Try running cmake and building a file. This is used for dynamically
    * loaded commands, not as part of the usual build process.
    */
-  virtual std::string GenerateBuildCommand(const char* makeProgram,
-                                           const char *projectName,
-                                           const char *projectDir,
-                                           const char* additionalOptions,
-                                           const char *targetName,
-                                           const char* config,
-                                           bool ignoreErrors,
-                                           bool fast);
+  virtual void GenerateBuildCommand(
+    std::vector<std::string>& makeCommand,
+    const char* makeProgram,
+    const char* projectName,
+    const char* projectDir,
+    const char* targetName,
+    const char* config,
+    bool fast,
+    std::vector<std::string> const& makeOptions = std::vector<std::string>()
+    );
 
   /**
    * Generate the all required files for building this project/tree. This

+ 29 - 37
Source/cmGlobalXCodeGenerator.cxx

@@ -257,39 +257,34 @@ void cmGlobalXCodeGenerator::EnableLanguage(std::vector<std::string>const&
 }
 
 //----------------------------------------------------------------------------
-std::string cmGlobalXCodeGenerator
-::GenerateBuildCommand(const char* makeProgram,
-                       const char *projectName,
-                       const char *projectDir,
-                       const char* additionalOptions,
-                       const char *targetName,
-                       const char* config,
-                       bool ignoreErrors,
-                       bool)
-{
-  // Config is not used yet
-  (void) ignoreErrors;
-  (void) projectDir;
-
+void
+cmGlobalXCodeGenerator::GenerateBuildCommand(
+  std::vector<std::string>& makeCommand,
+  const char* makeProgram,
+  const char* projectName,
+  const char* /*projectDir*/,
+  const char* targetName,
+  const char* config,
+  bool /*fast*/,
+  std::vector<std::string> const& makeOptions)
+{
   // now build the test
   if(makeProgram == 0 || !strlen(makeProgram))
     {
     cmSystemTools::Error(
       "Generator cannot find the appropriate make command.");
-    return "";
+    return;
     }
-  std::string makeCommand =
-    cmSystemTools::ConvertToOutputPath(makeProgram);
-  std::string lowerCaseCommand = makeCommand;
-  cmSystemTools::LowerCase(lowerCaseCommand);
+  makeCommand.push_back(makeProgram);
 
-  makeCommand += " -project ";
-  makeCommand += projectName;
-  makeCommand += ".xcode";
+  makeCommand.push_back("-project");
+  std::string projectArg = projectName;
+  projectArg += ".xcode";
   if(this->XcodeVersion > 20)
     {
-    makeCommand += "proj";
+    projectArg += "proj";
     }
+  makeCommand.push_back(projectArg);
 
   bool clean = false;
   if ( targetName && strcmp(targetName, "clean") == 0 )
@@ -299,13 +294,13 @@ std::string cmGlobalXCodeGenerator
     }
   if(clean)
     {
-    makeCommand += " clean";
+    makeCommand.push_back("clean");
     }
   else
     {
-    makeCommand += " build";
+    makeCommand.push_back("build");
     }
-  makeCommand += " -target ";
+  makeCommand.push_back("-target");
   // if it is a null string for config don't use it
   if(config && *config == 0)
     {
@@ -313,27 +308,24 @@ std::string cmGlobalXCodeGenerator
     }
   if (targetName && strlen(targetName))
     {
-    makeCommand += targetName;
+    makeCommand.push_back(targetName);
     }
   else
     {
-    makeCommand += "ALL_BUILD";
+    makeCommand.push_back("ALL_BUILD");
     }
   if(this->XcodeVersion == 15)
     {
-    makeCommand += " -buildstyle Development ";
+    makeCommand.push_back("-buildstyle");
+    makeCommand.push_back("Development");
     }
   else
     {
-    makeCommand += " -configuration ";
-    makeCommand += config?config:"Debug";
-    }
-  if ( additionalOptions )
-    {
-    makeCommand += " ";
-    makeCommand += additionalOptions;
+    makeCommand.push_back("-configuration");
+    makeCommand.push_back(config?config:"Debug");
     }
-  return makeCommand;
+  makeCommand.insert(makeCommand.end(),
+                     makeOptions.begin(), makeOptions.end());
 }
 
 //----------------------------------------------------------------------------

+ 10 - 8
Source/cmGlobalXCodeGenerator.h

@@ -53,14 +53,16 @@ public:
    * Try running cmake and building a file. This is used for dynalically
    * loaded commands, not as part of the usual build process.
    */
-  virtual std::string GenerateBuildCommand(const char* makeProgram,
-                                           const char *projectName,
-                                           const char *projectDir,
-                                           const char* additionalOptions,
-                                           const char *targetName,
-                                           const char* config,
-                                           bool ignoreErrors,
-                                           bool fast);
+  virtual void GenerateBuildCommand(
+    std::vector<std::string>& makeCommand,
+    const char* makeProgram,
+    const char* projectName,
+    const char* projectDir,
+    const char* targetName,
+    const char* config,
+    bool fast,
+    std::vector<std::string> const& makeOptions = std::vector<std::string>()
+    );
 
   /**
    * Generate the all required files for building this project/tree. This

+ 1 - 1
Source/cmake.cxx

@@ -2682,7 +2682,7 @@ int cmake::Build(const std::string& dir,
                     makeProgram.c_str(),
                     config.c_str(), clean, false, 0,
                     cmSystemTools::OUTPUT_PASSTHROUGH,
-                    0, nativeOptions);
+                    nativeOptions);
 }
 
 void cmake::WatchUnusedCli(const char* var)