فهرست منبع

BUG: Centralized generation of command line arguments in escaped form. This addresses bug#3786 for several platforms.

Brad King 19 سال پیش
والد
کامیت
2459ceb076

+ 2 - 2
Source/cmGlobalVisualStudio8Generator.cxx

@@ -130,12 +130,12 @@ void cmGlobalVisualStudio8Generator::Generate()
         std::string argH = "-H";
         argH += lg->Convert(mf->GetHomeDirectory(),
                             cmLocalGenerator::START_OUTPUT,
-                            cmLocalGenerator::SHELL, true);
+                            cmLocalGenerator::UNCHANGED, true);
         commandLine.push_back(argH);
         std::string argB = "-B";
         argB += lg->Convert(mf->GetHomeOutputDirectory(),
                             cmLocalGenerator::START_OUTPUT,
-                            cmLocalGenerator::SHELL, true);
+                            cmLocalGenerator::UNCHANGED, true);
         commandLine.push_back(argB);
         cmCustomCommandLines commandLines;
         commandLines.push_back(commandLine);

+ 28 - 50
Source/cmLocalGenerator.cxx

@@ -28,6 +28,8 @@
 #include "cmTest.h"
 #include "cmake.h"
 
+#include <cmsys/System.h>
+
 #include <ctype.h> // for isalpha
 
 cmLocalGenerator::cmLocalGenerator()
@@ -1896,56 +1898,6 @@ void cmLocalGenerator::AppendFlags(std::string& flags,
     }
 }
 
-//----------------------------------------------------------------------------
-std::string
-cmLocalGenerator::ConstructScript(const cmCustomCommandLines& commandLines,
-                                  const char* workingDirectory, 
-                                  const char* newline)
-                                  
-{
-  // Store the script in a string.
-  std::string script;
-  if(workingDirectory)
-    {
-    script += "cd ";
-    script += this->Convert(workingDirectory, START_OUTPUT, SHELL);
-    script += newline;
-    }
-  // for visual studio IDE add extra stuff to the PATH
-  // if CMAKE_MSVCIDE_RUN_PATH is set.
-  if(this->Makefile->GetDefinition("MSVC_IDE"))
-    {
-    const char* extraPath = 
-      this->Makefile->GetDefinition("CMAKE_MSVCIDE_RUN_PATH");
-    if(extraPath)
-      {
-      script += "set PATH=";
-      script += extraPath;
-      script += ";%PATH%";
-      script += newline;
-      }
-    }
-  // Write each command on a single line.
-  for(cmCustomCommandLines::const_iterator cl = commandLines.begin();
-      cl != commandLines.end(); ++cl)
-    {
-    // Start with the command name.
-    const cmCustomCommandLine& commandLine = *cl;
-    script += this->Convert(commandLine[0].c_str(),START_OUTPUT,SHELL);
-
-    // Add the arguments.
-    for(unsigned int j=1;j < commandLine.size(); ++j)
-      {
-      script += " ";
-      script += cmSystemTools::EscapeSpaces(commandLine[j].c_str());
-      }
-
-    // End the line.
-    script += newline;
-    }
-  return script;
-}
-
 //----------------------------------------------------------------------------
 std::string
 cmLocalGenerator::ConstructComment(const cmCustomCommand& cc,
@@ -2289,3 +2241,29 @@ cmLocalGenerator
   return (this->GlobalGenerator
           ->GetLanguageFromExtension(source.GetSourceExtension().c_str()));
 }
+
+//----------------------------------------------------------------------------
+std::string cmLocalGenerator::EscapeForShell(const char* str)
+{
+  std::string result;
+  if(this->WindowsShell)
+    {
+    int size = cmsysSystem_Windows_ShellArgumentSize(str);
+    std::vector<char> arg(size);
+    cmsysSystem_Windows_ShellArgument(str, &arg[0]);
+    result = &arg[0];
+    }
+  else
+    {
+    for(const char* c = str; *c; ++c)
+      {
+      if(*c == '\\' || *c == '\'' || *c == '"' || *c == ';' ||
+         *c == '(' || *c == ')')
+        {
+        result += "\\";
+        }
+      result += *c;
+      }
+    }
+  return result;
+}

+ 4 - 4
Source/cmLocalGenerator.h

@@ -202,10 +202,10 @@ public:
   };
 
 protected:
-  /** Construct a script from the given list of command lines.  */
-  std::string ConstructScript(const cmCustomCommandLines& commandLines,
-                              const char* workingDirectory,
-                              const char* newline = "\n");
+
+  /** Escape the given string to be used as a command line argument in
+      the native build system shell.  */
+  std::string EscapeForShell(const char* str);
 
   /** Construct a comment for a custom command.  */
   std::string ConstructComment(const cmCustomCommand& cc,

+ 1 - 10
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -931,16 +931,7 @@ cmLocalUnixMakefileGenerator3
       for(unsigned int j=1; j < commandLine.size(); ++j)
         {
         cmd += " ";
-        bool forceOn =  cmSystemTools::GetForceUnixPaths();
-        if(forceOn && this->WindowsShell)
-          {
-          cmSystemTools::SetForceUnixPaths(false);
-          }
-        cmd += cmSystemTools::EscapeSpaces(commandLine[j].c_str());
-        if(forceOn && this->WindowsShell)
-          {
-          cmSystemTools::SetForceUnixPaths(true);
-          }
+        cmd += this->EscapeForShell(commandLine[j].c_str());
         }
       commands1.push_back(cmd);
       }

+ 2 - 2
Source/cmLocalVisualStudio6Generator.cxx

@@ -223,12 +223,12 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt)
   std::string args;
   args = "-H";
   args += this->Convert(this->Makefile->GetHomeDirectory(),
-                        START_OUTPUT, SHELL, true);
+                        START_OUTPUT, UNCHANGED, true);
   commandLine.push_back(args);
   args = "-B";
   args += 
     this->Convert(this->Makefile->GetHomeOutputDirectory(), 
-                  START_OUTPUT, SHELL, true);
+                  START_OUTPUT, UNCHANGED, true);
   commandLine.push_back(args);
 
   std::string configFile = 

+ 2 - 2
Source/cmLocalVisualStudio7Generator.cxx

@@ -219,12 +219,12 @@ void cmLocalVisualStudio7Generator::AddVCProjBuildRule(cmTarget& tgt)
   std::string args;
   args = "-H";
   args += this->Convert(this->Makefile->GetHomeDirectory(), 
-                        START_OUTPUT, SHELL, true);
+                        START_OUTPUT, UNCHANGED, true);
   commandLine.push_back(args);
   args = "-B";
   args +=
     this->Convert(this->Makefile->GetHomeOutputDirectory(),
-                  START_OUTPUT, SHELL, true);
+                  START_OUTPUT, UNCHANGED, true);
   commandLine.push_back(args);
 
   std::string configFile =

+ 51 - 0
Source/cmLocalVisualStudioGenerator.cxx

@@ -23,6 +23,7 @@
 //----------------------------------------------------------------------------
 cmLocalVisualStudioGenerator::cmLocalVisualStudioGenerator()
 {
+  this->WindowsShell = true;
 }
 
 //----------------------------------------------------------------------------
@@ -103,3 +104,53 @@ void cmLocalVisualStudioGenerator::ComputeObjectNameRequirements
       }
     }
 }
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalVisualStudioGenerator
+::ConstructScript(const cmCustomCommandLines& commandLines,
+                  const char* workingDirectory,
+                  const char* newline)
+{
+  // Store the script in a string.
+  std::string script;
+  if(workingDirectory)
+    {
+    script += "cd ";
+    script += this->Convert(workingDirectory, START_OUTPUT, SHELL);
+    script += newline;
+    }
+  // for visual studio IDE add extra stuff to the PATH
+  // if CMAKE_MSVCIDE_RUN_PATH is set.
+  if(this->Makefile->GetDefinition("MSVC_IDE"))
+    {
+    const char* extraPath =
+      this->Makefile->GetDefinition("CMAKE_MSVCIDE_RUN_PATH");
+    if(extraPath)
+      {
+      script += "set PATH=";
+      script += extraPath;
+      script += ";%PATH%";
+      script += newline;
+      }
+    }
+  // Write each command on a single line.
+  for(cmCustomCommandLines::const_iterator cl = commandLines.begin();
+      cl != commandLines.end(); ++cl)
+    {
+    // Start with the command name.
+    const cmCustomCommandLine& commandLine = *cl;
+    script += this->Convert(commandLine[0].c_str(),START_OUTPUT,SHELL);
+
+    // Add the arguments.
+    for(unsigned int j=1;j < commandLine.size(); ++j)
+      {
+      script += " ";
+      script += this->EscapeForShell(commandLine[j].c_str());
+      }
+
+    // End the line.
+    script += newline;
+    }
+  return script;
+}

+ 6 - 0
Source/cmLocalVisualStudioGenerator.h

@@ -35,6 +35,12 @@ public:
   virtual ~cmLocalVisualStudioGenerator();
 
 protected:
+
+  /** Construct a script from the given list of command lines.  */
+  std::string ConstructScript(const cmCustomCommandLines& commandLines,
+                              const char* workingDirectory,
+                              const char* newline = "\n");
+
   // Safe object file name generation.
   void ComputeObjectNameRequirements(std::vector<cmSourceGroup> const&);
   bool SourceFileCompiles(const cmSourceFile* sf);