Răsfoiți Sursa

Merge topic 'custom-command-refactor'

53ea8b3 Merge branch 'imported-target-dependencies' into custom-command-refactor
1a29cca Remove cmLocalGenerator::GetRealLocation
542b517 Factor out common custom command generator
6fe5b3d Simplify VS generator ConstructScript interface
Brad King 15 ani în urmă
părinte
comite
533f5a2037

+ 2 - 0
Source/CMakeLists.txt

@@ -131,6 +131,8 @@ SET(SRCS
   cmComputeTargetDepends.cxx
   cmCustomCommand.cxx
   cmCustomCommand.h
+  cmCustomCommandGenerator.cxx
+  cmCustomCommandGenerator.h
   cmDefinitions.cxx
   cmDefinitions.h
   cmDepends.cxx

+ 64 - 0
Source/cmCustomCommandGenerator.cxx

@@ -0,0 +1,64 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmCustomCommandGenerator.h"
+
+#include "cmMakefile.h"
+#include "cmCustomCommand.h"
+#include "cmLocalGenerator.h"
+
+//----------------------------------------------------------------------------
+cmCustomCommandGenerator::cmCustomCommandGenerator(
+  cmCustomCommand const& cc, const char* config, cmMakefile* mf):
+  CC(cc), Config(config), Makefile(mf), LG(mf->GetLocalGenerator()),
+  OldStyle(cc.GetEscapeOldStyle()), MakeVars(cc.GetEscapeAllowMakeVars())
+{
+}
+
+//----------------------------------------------------------------------------
+unsigned int cmCustomCommandGenerator::GetNumberOfCommands() const
+{
+  return static_cast<unsigned int>(this->CC.GetCommandLines().size());
+}
+
+//----------------------------------------------------------------------------
+std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
+{
+  std::string const& argv0 = this->CC.GetCommandLines()[c][0];
+  cmTarget* target = this->Makefile->FindTargetToUse(argv0.c_str());
+  if(target && target->GetType() == cmTarget::EXECUTABLE &&
+     (target->IsImported() || !this->Makefile->IsOn("CMAKE_CROSSCOMPILING")))
+    {
+    return target->GetLocation(this->Config);
+    }
+  return argv0;
+}
+
+//----------------------------------------------------------------------------
+void
+cmCustomCommandGenerator
+::AppendArguments(unsigned int c, std::string& cmd) const
+{
+  cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
+  for(unsigned int j=1;j < commandLine.size(); ++j)
+    {
+    std::string const& arg = commandLine[j];
+    cmd += " ";
+    if(this->OldStyle)
+      {
+      cmd += this->LG->EscapeForShellOldStyle(arg.c_str());
+      }
+    else
+      {
+      cmd += this->LG->EscapeForShell(arg.c_str(), this->MakeVars);
+      }
+    }
+}

+ 37 - 0
Source/cmCustomCommandGenerator.h

@@ -0,0 +1,37 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmCustomCommandGenerator_h
+#define cmCustomCommandGenerator_h
+
+#include "cmStandardIncludes.h"
+
+class cmCustomCommand;
+class cmMakefile;
+class cmLocalGenerator;
+
+class cmCustomCommandGenerator
+{
+  cmCustomCommand const& CC;
+  const char* Config;
+  cmMakefile* Makefile;
+  cmLocalGenerator* LG;
+  bool OldStyle;
+  bool MakeVars;
+public:
+  cmCustomCommandGenerator(cmCustomCommand const& cc, const char* config,
+                           cmMakefile* mf);
+  unsigned int GetNumberOfCommands() const;
+  std::string GetCommand(unsigned int c) const;
+  void AppendArguments(unsigned int c, std::string& cmd) const;
+};
+
+#endif

+ 6 - 25
Source/cmGlobalXCodeGenerator.cxx

@@ -18,6 +18,7 @@
 #include "cmGeneratedFileStream.h"
 #include "cmComputeLinkInformation.h"
 #include "cmSourceFile.h"
+#include "cmCustomCommandGenerator.h"
 
 #include <cmsys/auto_ptr.hxx>
 
@@ -1314,8 +1315,7 @@ void  cmGlobalXCodeGenerator
     cmCustomCommand const& cc = *i;
     if(!cc.GetCommandLines().empty())
       {
-      bool escapeOldStyle = cc.GetEscapeOldStyle();
-      bool escapeAllowMakeVars = cc.GetEscapeAllowMakeVars();
+      cmCustomCommandGenerator ccg(cc, configName, this->CurrentMakefile);
       makefileStream << "\n";
       const std::vector<std::string>& outputs = cc.GetOutputs();
       if(!outputs.empty())
@@ -1348,20 +1348,15 @@ void  cmGlobalXCodeGenerator
         {
         std::string echo_cmd = "echo ";
         echo_cmd += (this->CurrentLocalGenerator->
-                     EscapeForShell(comment, escapeAllowMakeVars));
+                     EscapeForShell(comment, cc.GetEscapeAllowMakeVars()));
         makefileStream << "\t" << echo_cmd.c_str() << "\n";
         }
 
       // Add each command line to the set of commands.
-      for(cmCustomCommandLines::const_iterator cl =
-          cc.GetCommandLines().begin();
-          cl != cc.GetCommandLines().end(); ++cl)
+      for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
         {
         // Build the command line in a single string.
-        const cmCustomCommandLine& commandLine = *cl;
-        std::string cmd2 = this->CurrentLocalGenerator
-                         ->GetRealLocation(commandLine[0].c_str(), configName);
-
+        std::string cmd2 = ccg.GetCommand(c);
         cmSystemTools::ReplaceString(cmd2, "/./", "/");
         cmd2 = this->ConvertToRelativeForMake(cmd2.c_str());
         std::string cmd;
@@ -1372,21 +1367,7 @@ void  cmGlobalXCodeGenerator
           cmd += " && ";
           }
         cmd += cmd2;
-        for(unsigned int j=1; j < commandLine.size(); ++j)
-          {
-          cmd += " ";
-          if(escapeOldStyle)
-            {
-            cmd += (this->CurrentLocalGenerator
-                ->EscapeForShellOldStyle(commandLine[j].c_str()));
-            }
-          else
-            {
-            cmd += (this->CurrentLocalGenerator->
-                EscapeForShell(commandLine[j].c_str(),
-                               escapeAllowMakeVars));
-            }
-          }
+        ccg.AppendArguments(c, cmd);
         makefileStream << "\t" << cmd.c_str() << "\n";
         }
       }

+ 0 - 18
Source/cmLocalGenerator.cxx

@@ -1912,24 +1912,6 @@ bool cmLocalGenerator::GetRealDependency(const char* inName,
   return true;
 }
 
-//----------------------------------------------------------------------------
-std::string cmLocalGenerator::GetRealLocation(const char* inName,
-                                              const char* config)
-{
-  std::string outName=inName;
-  // Look for a CMake target with the given name, which is an executable 
-  // and which can be run
-  cmTarget* target = this->Makefile->FindTargetToUse(inName);
-  if ((target != 0)
-       && (target->GetType() == cmTarget::EXECUTABLE)
-       && ((this->Makefile->IsOn("CMAKE_CROSSCOMPILING") == false) 
-            || (target->IsImported() == true)))
-    {
-    outName = target->GetLocation( config );
-    }
-  return outName;
-}
-
 //----------------------------------------------------------------------------
 void cmLocalGenerator::AddSharedFlags(std::string& flags,
                                       const char* lang,

+ 0 - 5
Source/cmLocalGenerator.h

@@ -168,11 +168,6 @@ public:
   bool GetRealDependency(const char* name, const char* config,
                          std::string& dep);
 
-  /** Translate a command as given in CMake code to the location of the 
-      executable if the command is the name of a CMake executable target.
-      If that's not the case, just return the original name. */
-  std::string GetRealLocation(const char* inName, const char* config);
-
   ///! for existing files convert to output path and short path if spaces
   std::string ConvertToOutputForExisting(const char* remote,
                                          RelativeRoot local = START_OUTPUT);

+ 7 - 20
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -19,6 +19,7 @@
 #include "cmake.h"
 #include "cmVersion.h"
 #include "cmFileTimeComparison.h"
+#include "cmCustomCommandGenerator.h"
 
 // Include dependency scanners for supported languages.  Only the
 // C/C++ scanner is needed for bootstrapping CMake.
@@ -961,18 +962,15 @@ cmLocalUnixMakefileGenerator3
     {
     *content << dir;
     }
-  bool escapeOldStyle = cc.GetEscapeOldStyle();
-  bool escapeAllowMakeVars = cc.GetEscapeAllowMakeVars();
+  cmCustomCommandGenerator ccg(cc, this->ConfigurationName.c_str(),
+                               this->Makefile);
 
   // Add each command line to the set of commands.
   std::vector<std::string> commands1;
-  for(cmCustomCommandLines::const_iterator cl = cc.GetCommandLines().begin();
-      cl != cc.GetCommandLines().end(); ++cl)
+  for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
     {
     // Build the command line in a single string.
-    const cmCustomCommandLine& commandLine = *cl;
-    std::string cmd = GetRealLocation(commandLine[0].c_str(),
-                                      this->ConfigurationName.c_str());
+    std::string cmd = ccg.GetCommand(c);
     if (cmd.size())
       {
       // Use "call " before any invocations of .bat or .cmd files
@@ -1025,19 +1023,8 @@ cmLocalUnixMakefileGenerator3
       std::string launcher =
         this->MakeLauncher(cc, target, workingDir? NONE : START_OUTPUT);
       cmd = launcher + this->Convert(cmd.c_str(),NONE,SHELL);
-      for(unsigned int j=1; j < commandLine.size(); ++j)
-        {
-        cmd += " ";
-        if(escapeOldStyle)
-          {
-          cmd += this->EscapeForShellOldStyle(commandLine[j].c_str());
-          }
-        else
-          {
-          cmd += this->EscapeForShell(commandLine[j].c_str(),
-                                      escapeAllowMakeVars);
-          }
-        }
+
+      ccg.AppendArguments(c, cmd);
       if(content)
         {
         // Rule content does not include the launcher.

+ 2 - 13
Source/cmLocalVisualStudio6Generator.cxx

@@ -65,13 +65,7 @@ public:
       {
       this->Code += "\\\n\t";
       }
-    this->Code +=
-      this->LG->ConstructScript(cc.GetCommandLines(),
-                                cc.GetWorkingDirectory(),
-                                this->Config,
-                                cc.GetEscapeOldStyle(),
-                                cc.GetEscapeAllowMakeVars(),
-                                "\\\n\t");
+    this->Code += this->LG->ConstructScript(cc, this->Config, "\\\n\t");
     }
 private:
   cmLocalVisualStudio6Generator* LG;
@@ -659,12 +653,7 @@ cmLocalVisualStudio6Generator
     {
     std::string config = this->GetConfigName(*i);
     std::string script =
-      this->ConstructScript(command.GetCommandLines(), 
-                            command.GetWorkingDirectory(),
-                            config.c_str(),
-                            command.GetEscapeOldStyle(),
-                            command.GetEscapeAllowMakeVars(),
-                            "\\\n\t");
+      this->ConstructScript(command, config.c_str(), "\\\n\t");
       
     if (i == this->Configurations.begin())
       {

+ 2 - 12
Source/cmLocalVisualStudio7Generator.cxx

@@ -546,12 +546,7 @@ public:
       {
       this->Stream << this->LG->EscapeForXML("\n");
       }
-    std::string script =
-      this->LG->ConstructScript(cc.GetCommandLines(),
-                                cc.GetWorkingDirectory(),
-                                this->Config,
-                                cc.GetEscapeOldStyle(),
-                                cc.GetEscapeAllowMakeVars());
+    std::string script = this->LG->ConstructScript(cc, this->Config);
     this->Stream << this->LG->EscapeForXML(script.c_str());
     }
 private:
@@ -1591,12 +1586,7 @@ WriteCustomRule(std::ostream& fout,
            << this->EscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n";
       }
 
-    std::string script = 
-      this->ConstructScript(command.GetCommandLines(),
-                            command.GetWorkingDirectory(),
-                            i->c_str(),
-                            command.GetEscapeOldStyle(),
-                            command.GetEscapeAllowMakeVars());
+    std::string script = this->ConstructScript(command, i->c_str());
     fout << "\t\t\t\t\t<Tool\n"
          << "\t\t\t\t\tName=\"" << customTool << "\"\n"
          << "\t\t\t\t\tDescription=\"" 

+ 12 - 33
Source/cmLocalVisualStudioGenerator.cxx

@@ -14,6 +14,7 @@
 #include "cmMakefile.h"
 #include "cmSourceFile.h"
 #include "cmSystemTools.h"
+#include "cmCustomCommandGenerator.h"
 #include "windows.h"
 
 //----------------------------------------------------------------------------
@@ -163,13 +164,15 @@ std::string cmLocalVisualStudioGenerator::GetCheckForErrorLine()
 //----------------------------------------------------------------------------
 std::string
 cmLocalVisualStudioGenerator
-::ConstructScript(const cmCustomCommandLines& commandLines,
-                  const char* workingDirectory,
+::ConstructScript(cmCustomCommand const& cc,
                   const char* configName,
-                  bool escapeOldStyle,
-                  bool escapeAllowMakeVars,
                   const char* newline_text)
 {
+  const cmCustomCommandLines& commandLines = cc.GetCommandLines();
+  const char* workingDirectory = cc.GetWorkingDirectory();
+  cmCustomCommandGenerator ccg(cc, configName, this->Makefile);
+  RelativeRoot relativeRoot = workingDirectory? NONE : START_OUTPUT;
+
   // Avoid leading or trailing newlines.
   const char* newline = "";
 
@@ -208,40 +211,16 @@ cmLocalVisualStudioGenerator
       }
     }
   // Write each command on a single line.
-  for(cmCustomCommandLines::const_iterator cl = commandLines.begin();
-      cl != commandLines.end(); ++cl)
+  for(unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c)
     {
     // Start a new line.
     script += newline;
     newline = newline_text;
 
-    // Start with the command name.
-    const cmCustomCommandLine& commandLine = *cl;
-    std::string commandName = this->GetRealLocation(commandLine[0].c_str(), 
-                                                    configName);
-    if(!workingDirectory)
-      {
-      script += this->Convert(commandName.c_str(),START_OUTPUT,SHELL);
-      }
-    else
-      {
-      script += this->Convert(commandName.c_str(),NONE,SHELL);
-      }
-
-    // Add the arguments.
-    for(unsigned int j=1;j < commandLine.size(); ++j)
-      {
-      script += " ";
-      if(escapeOldStyle)
-        {
-        script += this->EscapeForShellOldStyle(commandLine[j].c_str());
-        }
-      else
-        {
-        script += this->EscapeForShell(commandLine[j].c_str(),
-                                       escapeAllowMakeVars);
-        }
-      }
+    // Add this command line.
+    std::string cmd = ccg.GetCommand(c);
+    script += this->Convert(cmd.c_str(), relativeRoot, SHELL);
+    ccg.AppendArguments(c, script);
 
     // After each custom command, check for an error result.
     // If there was an error, jump to the VCReportError label,

+ 2 - 4
Source/cmLocalVisualStudioGenerator.h

@@ -18,6 +18,7 @@
 
 class cmSourceFile;
 class cmSourceGroup;
+class cmCustomCommand;
 
 /** \class cmLocalVisualStudioGenerator
  * \brief Base class for Visual Studio generators.
@@ -32,11 +33,8 @@ public:
   virtual ~cmLocalVisualStudioGenerator();
 
   /** Construct a script from the given list of command lines.  */
-  std::string ConstructScript(const cmCustomCommandLines& commandLines,
-                              const char* workingDirectory,
+  std::string ConstructScript(cmCustomCommand const& cc,
                               const char* configName,
-                              bool escapeOldStyle,
-                              bool escapeAllowMakeVars,
                               const char* newline = "\n");
 
   /** Line of batch file text that skips to the end after

+ 2 - 14
Source/cmVisualStudio10TargetGenerator.cxx

@@ -376,13 +376,7 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
       i != configs->end(); ++i)
     {
     std::string script =
-      cmVS10EscapeXML(
-        lg->ConstructScript(command.GetCommandLines(),
-                            command.GetWorkingDirectory(),
-                            i->c_str(),
-                            command.GetEscapeOldStyle(),
-                            command.GetEscapeAllowMakeVars())
-        );
+      cmVS10EscapeXML(lg->ConstructScript(command, i->c_str()));
     this->WritePlatformConfigTag("Message",i->c_str(), 3);
     (*this->BuildFileStream ) << cmVS10EscapeXML(comment) << "</Message>\n";
     this->WritePlatformConfigTag("Command", i->c_str(), 3);
@@ -1469,13 +1463,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
     script += pre;
     pre = "\n";
     script +=
-      cmVS10EscapeXML(
-        lg->ConstructScript(command.GetCommandLines(),
-                            command.GetWorkingDirectory(),
-                            configName.c_str(),
-                            command.GetEscapeOldStyle(),
-                            command.GetEscapeAllowMakeVars())
-        );
+      cmVS10EscapeXML(lg->ConstructScript(command, configName.c_str()));
     }
   comment = cmVS10EscapeComment(comment);
   this->WriteString("<Message>",3);

+ 1 - 0
bootstrap

@@ -215,6 +215,7 @@ CMAKE_CXX_SOURCES="\
   cmTarget \
   cmTest \
   cmCustomCommand \
+  cmCustomCommandGenerator \
   cmDocumentVariables \
   cmCacheManager \
   cmListFileCache \