Ver código fonte

Generalize cmCustomCommandGenerator to more fields

Until now the cmCustomCommandGenerator was used only to compute the
command lines of a custom command.  Generalize it to get the comment,
working directory, dependencies, and outputs of custom commands.  Update
use in all generators to support this.
Brad King 12 anos atrás
pai
commit
bc993f277e

+ 24 - 0
Source/cmCustomCommandGenerator.cxx

@@ -71,3 +71,27 @@ cmCustomCommandGenerator
       }
     }
 }
+
+//----------------------------------------------------------------------------
+const char* cmCustomCommandGenerator::GetComment() const
+{
+  return this->CC.GetComment();
+}
+
+//----------------------------------------------------------------------------
+std::string cmCustomCommandGenerator::GetWorkingDirectory() const
+{
+  return this->CC.GetWorkingDirectory();
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> const& cmCustomCommandGenerator::GetOutputs() const
+{
+  return this->CC.GetOutputs();
+}
+
+//----------------------------------------------------------------------------
+std::vector<std::string> const& cmCustomCommandGenerator::GetDepends() const
+{
+  return this->CC.GetDepends();
+}

+ 5 - 0
Source/cmCustomCommandGenerator.h

@@ -33,9 +33,14 @@ public:
                            const std::string& config,
                            cmMakefile* mf);
   ~cmCustomCommandGenerator();
+  cmCustomCommand const& GetCC() const { return this->CC; }
   unsigned int GetNumberOfCommands() const;
   std::string GetCommand(unsigned int c) const;
   void AppendArguments(unsigned int c, std::string& cmd) const;
+  const char* GetComment() const;
+  std::string GetWorkingDirectory() const;
+  std::vector<std::string> const& GetOutputs() const;
+  std::vector<std::string> const& GetDepends() const;
 };
 
 #endif

+ 14 - 15
Source/cmGlobalXCodeGenerator.cxx

@@ -1546,10 +1546,10 @@ void  cmGlobalXCodeGenerator
   for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
       i != commands.end(); ++i)
     {
-    cmCustomCommand const& cc = *i;
-    if(!cc.GetCommandLines().empty())
+    cmCustomCommandGenerator ccg(*i, configName, this->CurrentMakefile);
+    if(ccg.GetNumberOfCommands() > 0)
       {
-      const std::vector<std::string>& outputs = cc.GetOutputs();
+      const std::vector<std::string>& outputs = ccg.GetOutputs();
       if(!outputs.empty())
         {
         for(std::vector<std::string>::const_iterator o = outputs.begin();
@@ -1573,8 +1573,8 @@ void  cmGlobalXCodeGenerator
         {
         cmOStringStream str;
         str << "_buildpart_" << count++ ;
-        tname[&cc] = std::string(target.GetName()) + str.str();
-        makefileStream << "\\\n\t" << tname[&cc];
+        tname[&ccg.GetCC()] = std::string(target.GetName()) + str.str();
+        makefileStream << "\\\n\t" << tname[&ccg.GetCC()];
         }
       }
     }
@@ -1582,12 +1582,11 @@ void  cmGlobalXCodeGenerator
   for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
       i != commands.end(); ++i)
     {
-    cmCustomCommand const& cc = *i;
-    if(!cc.GetCommandLines().empty())
+    cmCustomCommandGenerator ccg(*i, configName, this->CurrentMakefile);
+    if(ccg.GetNumberOfCommands() > 0)
       {
-      cmCustomCommandGenerator ccg(cc, configName, this->CurrentMakefile);
       makefileStream << "\n";
-      const std::vector<std::string>& outputs = cc.GetOutputs();
+      const std::vector<std::string>& outputs = ccg.GetOutputs();
       if(!outputs.empty())
         {
         // There is at least one output, start the rule for it
@@ -1598,11 +1597,11 @@ void  cmGlobalXCodeGenerator
       else
         {
         // There are no outputs.  Use the generated force rule name.
-        makefileStream << tname[&cc] << ": ";
+        makefileStream << tname[&ccg.GetCC()] << ": ";
         }
       for(std::vector<std::string>::const_iterator d =
-          cc.GetDepends().begin();
-          d != cc.GetDepends().end(); ++d)
+          ccg.GetDepends().begin();
+          d != ccg.GetDepends().end(); ++d)
         {
         std::string dep;
         if(this->CurrentLocalGenerator
@@ -1614,11 +1613,11 @@ void  cmGlobalXCodeGenerator
         }
       makefileStream << "\n";
 
-      if(const char* comment = cc.GetComment())
+      if(const char* comment = ccg.GetComment())
         {
         std::string echo_cmd = "echo ";
         echo_cmd += (this->CurrentLocalGenerator->
-                     EscapeForShell(comment, cc.GetEscapeAllowMakeVars()));
+          EscapeForShell(comment, ccg.GetCC().GetEscapeAllowMakeVars()));
         makefileStream << "\t" << echo_cmd.c_str() << "\n";
         }
 
@@ -1630,7 +1629,7 @@ void  cmGlobalXCodeGenerator
         cmSystemTools::ReplaceString(cmd2, "/./", "/");
         cmd2 = this->ConvertToRelativeForMake(cmd2.c_str());
         std::string cmd;
-        std::string wd = cc.GetWorkingDirectory();
+        std::string wd = ccg.GetWorkingDirectory();
         if(!wd.empty())
           {
           cmd += "cd ";

+ 7 - 6
Source/cmLocalGenerator.cxx

@@ -22,6 +22,7 @@
 #include "cmSourceFile.h"
 #include "cmTest.h"
 #include "cmTestGenerator.h"
+#include "cmCustomCommandGenerator.h"
 #include "cmVersion.h"
 #include "cmake.h"
 
@@ -2482,23 +2483,23 @@ void cmLocalGenerator::AppendFeatureOptions(
 
 //----------------------------------------------------------------------------
 std::string
-cmLocalGenerator::ConstructComment(const cmCustomCommand& cc,
+cmLocalGenerator::ConstructComment(cmCustomCommandGenerator const& ccg,
                                    const char* default_comment)
 {
   // Check for a comment provided with the command.
-  if(cc.GetComment())
+  if(ccg.GetComment())
     {
-    return cc.GetComment();
+    return ccg.GetComment();
     }
 
   // Construct a reasonable default comment if possible.
-  if(!cc.GetOutputs().empty())
+  if(!ccg.GetOutputs().empty())
     {
     std::string comment;
     comment = "Generating ";
     const char* sep = "";
-    for(std::vector<std::string>::const_iterator o = cc.GetOutputs().begin();
-        o != cc.GetOutputs().end(); ++o)
+    for(std::vector<std::string>::const_iterator o = ccg.GetOutputs().begin();
+        o != ccg.GetOutputs().end(); ++o)
       {
       comment += sep;
       comment += this->Convert(*o, cmLocalGenerator::START_OUTPUT);

+ 2 - 1
Source/cmLocalGenerator.h

@@ -21,6 +21,7 @@ class cmTarget;
 class cmTargetManifest;
 class cmSourceFile;
 class cmCustomCommand;
+class cmCustomCommandGenerator;
 
 /** \class cmLocalGenerator
  * \brief Create required build files for a directory.
@@ -350,7 +351,7 @@ public:
                                   const std::string& targetName,
                                   const char* fname);
   /** Construct a comment for a custom command.  */
-  std::string ConstructComment(const cmCustomCommand& cc,
+  std::string ConstructComment(cmCustomCommandGenerator const& ccg,
                                const char* default_comment = "");
   // Compute object file names.
   std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source,

+ 18 - 15
Source/cmLocalNinjaGenerator.cxx

@@ -303,10 +303,11 @@ cmLocalNinjaGenerator
   this->GetGlobalNinjaGenerator()->AppendTargetDepends(target, outputs);
 }
 
-void cmLocalNinjaGenerator::AppendCustomCommandDeps(const cmCustomCommand *cc,
-                                                    cmNinjaDeps &ninjaDeps)
+void cmLocalNinjaGenerator::AppendCustomCommandDeps(
+  cmCustomCommandGenerator const& ccg,
+  cmNinjaDeps &ninjaDeps)
 {
-  const std::vector<std::string> &deps = cc->GetDepends();
+  const std::vector<std::string> &deps = ccg.GetDepends();
   for (std::vector<std::string>::const_iterator i = deps.begin();
        i != deps.end(); ++i) {
     std::string dep;
@@ -359,12 +360,12 @@ std::string cmLocalNinjaGenerator::BuildCommandLine(
   return cmd.str();
 }
 
-void cmLocalNinjaGenerator::AppendCustomCommandLines(const cmCustomCommand *cc,
-                                            std::vector<std::string> &cmdLines)
+void cmLocalNinjaGenerator::AppendCustomCommandLines(
+  cmCustomCommandGenerator const& ccg,
+  std::vector<std::string> &cmdLines)
 {
-  cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this->Makefile);
   if (ccg.GetNumberOfCommands() > 0) {
-    std::string wd = cc->GetWorkingDirectory();
+    std::string wd = ccg.GetWorkingDirectory();
     if (wd.empty())
       wd = this->GetMakefile()->GetStartOutputDirectory();
 
@@ -378,7 +379,7 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines(const cmCustomCommand *cc,
     cmdLines.push_back(cdCmd.str());
   }
 
-  std::string launcher = this->MakeCustomLauncher(*cc);
+  std::string launcher = this->MakeCustomLauncher(ccg);
 
   for (unsigned i = 0; i != ccg.GetNumberOfCommands(); ++i) {
     cmdLines.push_back(launcher +
@@ -396,19 +397,21 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
   if (this->GetGlobalNinjaGenerator()->SeenCustomCommand(cc))
     return;
 
-  const std::vector<std::string> &outputs = cc->GetOutputs();
+  cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this->Makefile);
+
+  const std::vector<std::string> &outputs = ccg.GetOutputs();
   cmNinjaDeps ninjaOutputs(outputs.size()), ninjaDeps;
 
   std::transform(outputs.begin(), outputs.end(),
                  ninjaOutputs.begin(), MapToNinjaPath());
-  this->AppendCustomCommandDeps(cc, ninjaDeps);
+  this->AppendCustomCommandDeps(ccg, ninjaDeps);
 
   for (cmNinjaDeps::iterator i = ninjaOutputs.begin(); i != ninjaOutputs.end();
        ++i)
     this->GetGlobalNinjaGenerator()->SeenCustomCommandOutput(*i);
 
   std::vector<std::string> cmdLines;
-  this->AppendCustomCommandLines(cc, cmdLines);
+  this->AppendCustomCommandLines(ccg, cmdLines);
 
   if (cmdLines.empty()) {
     this->GetGlobalNinjaGenerator()->WritePhonyBuild(
@@ -423,7 +426,7 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
   } else {
     this->GetGlobalNinjaGenerator()->WriteCustomCommandBuild(
       this->BuildCommandLine(cmdLines),
-      this->ConstructComment(*cc),
+      this->ConstructComment(ccg),
       "Custom command for " + ninjaOutputs[0],
       ninjaOutputs,
       ninjaDeps,
@@ -472,7 +475,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
 }
 
 std::string cmLocalNinjaGenerator::MakeCustomLauncher(
-  const cmCustomCommand& cc)
+  cmCustomCommandGenerator const& ccg)
 {
   const char* property = "RULE_LAUNCH_CUSTOM";
   const char* property_value = this->Makefile->GetProperty(property);
@@ -487,11 +490,11 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
   RuleVariables vars;
   vars.RuleLauncher = property;
   std::string output;
-  const std::vector<std::string>& outputs = cc.GetOutputs();
+  const std::vector<std::string>& outputs = ccg.GetOutputs();
   if(!outputs.empty())
   {
     RelativeRoot relative_root =
-      cc.GetWorkingDirectory().empty() ? START_OUTPUT : NONE;
+      ccg.GetWorkingDirectory().empty() ? START_OUTPUT : NONE;
 
     output = this->Convert(outputs[0], relative_root, SHELL);
   }

+ 4 - 3
Source/cmLocalNinjaGenerator.h

@@ -16,6 +16,7 @@
 #  include "cmLocalGenerator.h"
 #  include "cmNinjaTypes.h"
 
+class cmCustomCommandGenerator;
 class cmGlobalNinjaGenerator;
 class cmGeneratedFileStream;
 class cmake;
@@ -92,9 +93,9 @@ public:
   void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs);
 
   void AddCustomCommandTarget(cmCustomCommand const* cc, cmTarget* target);
-  void AppendCustomCommandLines(const cmCustomCommand *cc,
+  void AppendCustomCommandLines(cmCustomCommandGenerator const& ccg,
                                 std::vector<std::string> &cmdLines);
-  void AppendCustomCommandDeps(const cmCustomCommand *cc,
+  void AppendCustomCommandDeps(cmCustomCommandGenerator const& ccg,
                                cmNinjaDeps &ninjaDeps);
 
   virtual std::string ConvertToLinkReference(std::string const& lib,
@@ -124,7 +125,7 @@ private:
 
   void WriteCustomCommandBuildStatements();
 
-  std::string MakeCustomLauncher(const cmCustomCommand& cc);
+  std::string MakeCustomLauncher(cmCustomCommandGenerator const& ccg);
 
   std::string ConfigName;
   std::string HomeRelativeOutputPath;

+ 18 - 16
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -960,7 +960,9 @@ cmLocalUnixMakefileGenerator3
   for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
       i != ccs.end(); ++i)
     {
-    this->AppendCustomDepend(depends, *i);
+    cmCustomCommandGenerator ccg(*i, this->ConfigurationName,
+                                 this->Makefile);
+    this->AppendCustomDepend(depends, ccg);
     }
 }
 
@@ -968,10 +970,10 @@ cmLocalUnixMakefileGenerator3
 void
 cmLocalUnixMakefileGenerator3
 ::AppendCustomDepend(std::vector<std::string>& depends,
-                     const cmCustomCommand& cc)
+                     cmCustomCommandGenerator const& ccg)
 {
-  for(std::vector<std::string>::const_iterator d = cc.GetDepends().begin();
-      d != cc.GetDepends().end(); ++d)
+  for(std::vector<std::string>::const_iterator d = ccg.GetDepends().begin();
+      d != ccg.GetDepends().end(); ++d)
     {
     // Lookup the real name of the dependency in case it is a CMake target.
     std::string dep;
@@ -994,7 +996,9 @@ cmLocalUnixMakefileGenerator3
   for(std::vector<cmCustomCommand>::const_iterator i = ccs.begin();
       i != ccs.end(); ++i)
     {
-    this->AppendCustomCommand(commands, *i, target, true, relative);
+    cmCustomCommandGenerator ccg(*i, this->ConfigurationName,
+                                 this->Makefile);
+    this->AppendCustomCommand(commands, ccg, target, true, relative);
     }
 }
 
@@ -1002,7 +1006,7 @@ cmLocalUnixMakefileGenerator3
 void
 cmLocalUnixMakefileGenerator3
 ::AppendCustomCommand(std::vector<std::string>& commands,
-                      const cmCustomCommand& cc,
+                      cmCustomCommandGenerator const& ccg,
                       cmTarget* target,
                       bool echo_comment,
                       cmLocalGenerator::RelativeRoot relative,
@@ -1014,8 +1018,8 @@ cmLocalUnixMakefileGenerator3
   // their comments generated elsewhere.
   if(echo_comment)
     {
-    const char* comment = cc.GetComment();
-    if(comment && *comment)
+    const char* comment = ccg.GetComment();
+    if(comment && !*comment)
       {
       this->AppendEcho(commands, comment,
                        cmLocalUnixMakefileGenerator3::EchoGenerate);
@@ -1024,7 +1028,7 @@ cmLocalUnixMakefileGenerator3
 
   // if the command specified a working directory use it.
   std::string dir  = this->Makefile->GetStartOutputDirectory();
-  std::string workingDir = cc.GetWorkingDirectory();
+  std::string workingDir = ccg.GetWorkingDirectory();
   if(!workingDir.empty())
     {
     dir = workingDir;
@@ -1033,8 +1037,6 @@ cmLocalUnixMakefileGenerator3
     {
     *content << dir;
     }
-  cmCustomCommandGenerator ccg(cc, this->ConfigurationName,
-                               this->Makefile);
 
   // Add each command line to the set of commands.
   std::vector<std::string> commands1;
@@ -1079,7 +1081,7 @@ cmLocalUnixMakefileGenerator3
         cmd = "./" + cmd;
         }
       std::string launcher =
-        this->MakeLauncher(cc, target,
+        this->MakeLauncher(ccg, target,
                            workingDir.empty()? START_OUTPUT : NONE);
       cmd = launcher + this->ConvertShellCommand(cmd, NONE);
 
@@ -1134,9 +1136,9 @@ cmLocalUnixMakefileGenerator3
 
 //----------------------------------------------------------------------------
 std::string
-cmLocalUnixMakefileGenerator3::MakeLauncher(const cmCustomCommand& cc,
-                                            cmTarget* target,
-                                            RelativeRoot relative)
+cmLocalUnixMakefileGenerator3::MakeLauncher(
+  cmCustomCommandGenerator const& ccg,
+  cmTarget* target, RelativeRoot relative)
 {
   // Short-circuit if there is no launcher.
   const char* prop = "RULE_LAUNCH_CUSTOM";
@@ -1152,7 +1154,7 @@ cmLocalUnixMakefileGenerator3::MakeLauncher(const cmCustomCommand& cc,
   vars.RuleLauncher = prop;
   vars.CMTarget = target;
   std::string output;
-  const std::vector<std::string>& outputs = cc.GetOutputs();
+  const std::vector<std::string>& outputs = ccg.GetOutputs();
   if(!outputs.empty())
     {
     output = this->Convert(outputs[0], relative, SHELL);

+ 5 - 4
Source/cmLocalUnixMakefileGenerator3.h

@@ -18,6 +18,7 @@
 #include "cmDepends.h"
 
 class cmCustomCommand;
+class cmCustomCommandGenerator;
 class cmDependInformation;
 class cmDepends;
 class cmMakefileTargetGenerator;
@@ -289,14 +290,14 @@ protected:
   void AppendCustomDepends(std::vector<std::string>& depends,
                            const std::vector<cmCustomCommand>& ccs);
   void AppendCustomDepend(std::vector<std::string>& depends,
-                          const cmCustomCommand& cc);
+                          cmCustomCommandGenerator const& cc);
   void AppendCustomCommands(std::vector<std::string>& commands,
                             const std::vector<cmCustomCommand>& ccs,
                             cmTarget* target,
                             cmLocalGenerator::RelativeRoot relative =
                             cmLocalGenerator::HOME_OUTPUT);
   void AppendCustomCommand(std::vector<std::string>& commands,
-                           const cmCustomCommand& cc,
+                           cmCustomCommandGenerator const& ccg,
                            cmTarget* target,
                            bool echo_comment=false,
                            cmLocalGenerator::RelativeRoot relative =
@@ -313,8 +314,8 @@ protected:
 
 private:
   std::string ConvertShellCommand(std::string const& cmd, RelativeRoot root);
-  std::string MakeLauncher(const cmCustomCommand& cc, cmTarget* target,
-                           RelativeRoot relative);
+  std::string MakeLauncher(cmCustomCommandGenerator const& ccg,
+                           cmTarget* target, RelativeRoot relative);
 
   friend class cmMakefileTargetGenerator;
   friend class cmMakefileExecutableTargetGenerator;

+ 23 - 16
Source/cmLocalVisualStudio6Generator.cxx

@@ -16,6 +16,7 @@
 #include "cmSourceFile.h"
 #include "cmCacheManager.h"
 #include "cmGeneratorTarget.h"
+#include "cmCustomCommandGenerator.h"
 #include "cmake.h"
 
 #include "cmComputeLinkInformation.h"
@@ -59,6 +60,7 @@ public:
     }
   void Write(cmCustomCommand const& cc)
     {
+    cmCustomCommandGenerator ccg(cc, this->Config, this->LG->GetMakefile());
     if(this->First)
       {
       this->Code += this->Event + "_Cmds=";
@@ -68,7 +70,7 @@ public:
       {
       this->Code += "\\\n\t";
       }
-    this->Code += this->LG->ConstructScript(cc, this->Config, "\\\n\t");
+    this->Code += this->LG->ConstructScript(ccg, "\\\n\t");
     }
 private:
   cmLocalVisualStudio6Generator* LG;
@@ -575,14 +577,18 @@ cmLocalVisualStudio6Generator
                            target.GetName().size() + 30)];
   sprintf(output,"%s/%s_force_%i", this->Makefile->GetStartOutputDirectory(),
           target.GetName().c_str(), count);
-  std::string comment = this->ConstructComment(origCommand, "<hack>");
+  const char* comment = origCommand.GetComment();
+  if(!comment && origCommand.GetOutputs().empty())
+    {
+    comment = "<hack>";
+    }
 
   // Add the rule with the given dependencies and commands.
   std::string no_main_dependency = "";
   if(cmSourceFile* outsf =
      this->Makefile->AddCustomCommandToOutput(
        output, depends, no_main_dependency,
-       origCommand.GetCommandLines(), comment.c_str(),
+       origCommand.GetCommandLines(), comment,
        origCommand.GetWorkingDirectory().c_str()))
     {
     target.AddSourceFile(outsf);
@@ -604,20 +610,21 @@ cmLocalVisualStudio6Generator
                   const cmCustomCommand& command,
                   const char* flags)
 {
-  std::string comment =
-    this->ConstructComment(command, "Building Custom Rule $(InputPath)");
-  if(comment == "<hack>")
-    {
-    comment = "";
-    }
-
   // Write the rule for each configuration.
   std::vector<std::string>::iterator i;
   for(i = this->Configurations.begin(); i != this->Configurations.end(); ++i)
     {
     std::string config = this->GetConfigName(*i);
+    cmCustomCommandGenerator ccg(command, config, this->Makefile);
+    std::string comment =
+      this->ConstructComment(ccg, "Building Custom Rule $(InputPath)");
+    if(comment == "<hack>")
+      {
+      comment = "";
+      }
+
     std::string script =
-      this->ConstructScript(command, config.c_str(), "\\\n\t");
+      this->ConstructScript(ccg, "\\\n\t");
 
     if (i == this->Configurations.begin())
       {
@@ -634,8 +641,8 @@ cmLocalVisualStudio6Generator
     // Write out the dependencies for the rule.
     fout << "USERDEP__HACK=";
     for(std::vector<std::string>::const_iterator d =
-          command.GetDepends().begin();
-        d != command.GetDepends().end();
+          ccg.GetDepends().begin();
+        d != ccg.GetDepends().end();
         ++d)
       {
       // Lookup the real name of the dependency in case it is a CMake target.
@@ -655,7 +662,7 @@ cmLocalVisualStudio6Generator
       fout << " " << comment.c_str();
       }
     fout << "\n\n";
-    if(command.GetOutputs().empty())
+    if(ccg.GetOutputs().empty())
       {
       fout << source
            << "_force :  \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"\n\t";
@@ -664,8 +671,8 @@ cmLocalVisualStudio6Generator
     else
       {
       for(std::vector<std::string>::const_iterator o =
-          command.GetOutputs().begin();
-          o != command.GetOutputs().end();
+          ccg.GetOutputs().begin();
+          o != ccg.GetOutputs().end();
           ++o)
         {
         // Write a rule for every output generated by this command.

+ 13 - 11
Source/cmLocalVisualStudio7Generator.cxx

@@ -18,6 +18,7 @@
 #include "cmSourceFile.h"
 #include "cmCacheManager.h"
 #include "cmGeneratorTarget.h"
+#include "cmCustomCommandGenerator.h"
 #include "cmake.h"
 
 #include "cmComputeLinkInformation.h"
@@ -609,9 +610,10 @@ public:
     }
   void Write(cmCustomCommand const& cc)
     {
+    cmCustomCommandGenerator ccg(cc, this->Config, this->LG->GetMakefile());
     if(this->First)
       {
-      const char* comment = cc.GetComment();
+      const char* comment = ccg.GetComment();
       if(comment && *comment)
         {
         this->Stream << "\nDescription=\""
@@ -624,7 +626,7 @@ public:
       {
       this->Stream << this->LG->EscapeForXML("\n");
       }
-    std::string script = this->LG->ConstructScript(cc, this->Config);
+    std::string script = this->LG->ConstructScript(ccg);
     this->Stream << this->LG->EscapeForXML(script.c_str());
     }
 private:
@@ -1791,8 +1793,6 @@ WriteCustomRule(std::ostream& fout,
                 const cmCustomCommand& command,
                 FCInfo& fcinfo)
 {
-  std::string comment = this->ConstructComment(command);
-
   // Write the rule for each configuration.
   std::vector<std::string>::iterator i;
   std::vector<std::string> *configs =
@@ -1810,6 +1810,7 @@ WriteCustomRule(std::ostream& fout,
     }
   for(i = configs->begin(); i != configs->end(); ++i)
     {
+    cmCustomCommandGenerator ccg(command, *i, this->Makefile);
     cmLVS7GFileConfig const& fc = fcinfo.FileConfigMap[*i];
     fout << "\t\t\t\t<FileConfiguration\n";
     fout << "\t\t\t\t\tName=\"" << *i << "|" << this->PlatformName << "\">\n";
@@ -1821,7 +1822,8 @@ WriteCustomRule(std::ostream& fout,
            << this->EscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n";
       }
 
-    std::string script = this->ConstructScript(command, i->c_str());
+    std::string comment = this->ConstructComment(ccg);
+    std::string script = this->ConstructScript(ccg);
     if(this->FortranProject)
       {
       cmSystemTools::ReplaceString(script, "$(Configuration)", i->c_str());
@@ -1833,7 +1835,7 @@ WriteCustomRule(std::ostream& fout,
          << "\t\t\t\t\tCommandLine=\""
          << this->EscapeForXML(script.c_str()) << "\"\n"
          << "\t\t\t\t\tAdditionalDependencies=\"";
-    if(command.GetDepends().empty())
+    if(ccg.GetDepends().empty())
       {
       // There are no real dependencies.  Produce an artificial one to
       // make sure the rule runs reliably.
@@ -1848,8 +1850,8 @@ WriteCustomRule(std::ostream& fout,
       {
       // Write out the dependencies for the rule.
       for(std::vector<std::string>::const_iterator d =
-          command.GetDepends().begin();
-          d != command.GetDepends().end();
+          ccg.GetDepends().begin();
+          d != ccg.GetDepends().end();
           ++d)
         {
         // Get the real name of the dependency in case it is a CMake target.
@@ -1863,7 +1865,7 @@ WriteCustomRule(std::ostream& fout,
       }
     fout << "\"\n";
     fout << "\t\t\t\t\tOutputs=\"";
-    if(command.GetOutputs().empty())
+    if(ccg.GetOutputs().empty())
       {
       fout << source << "_force";
       }
@@ -1872,8 +1874,8 @@ WriteCustomRule(std::ostream& fout,
       // Write a rule for the output generated by this command.
       const char* sep = "";
       for(std::vector<std::string>::const_iterator o =
-          command.GetOutputs().begin();
-          o != command.GetOutputs().end();
+          ccg.GetOutputs().begin();
+          o != ccg.GetOutputs().end();
           ++o)
         {
         fout << sep << this->ConvertToXMLOutputPathSingle(o->c_str());

+ 2 - 4
Source/cmLocalVisualStudioGenerator.cxx

@@ -79,13 +79,11 @@ const char* cmLocalVisualStudioGenerator::GetReportErrorLabel() const
 //----------------------------------------------------------------------------
 std::string
 cmLocalVisualStudioGenerator
-::ConstructScript(cmCustomCommand const& cc,
-                  const std::string& configName,
+::ConstructScript(cmCustomCommandGenerator const& ccg,
                   const std::string& newline_text)
 {
   bool useLocal = this->CustomCommandUseLocal();
-  std::string workingDirectory = cc.GetWorkingDirectory();
-  cmCustomCommandGenerator ccg(cc, configName, this->Makefile);
+  std::string workingDirectory = ccg.GetWorkingDirectory();
   RelativeRoot relativeRoot = workingDirectory.empty()? START_OUTPUT : NONE;
 
   // Avoid leading or trailing newlines.

+ 2 - 2
Source/cmLocalVisualStudioGenerator.h

@@ -19,6 +19,7 @@
 class cmSourceFile;
 class cmSourceGroup;
 class cmCustomCommand;
+class cmCustomCommandGenerator;
 
 /** \class cmLocalVisualStudioGenerator
  * \brief Base class for Visual Studio generators.
@@ -46,8 +47,7 @@ public:
   virtual ~cmLocalVisualStudioGenerator();
 
   /** Construct a script from the given list of command lines.  */
-  std::string ConstructScript(cmCustomCommand const& cc,
-                              const std::string& configName,
+  std::string ConstructScript(cmCustomCommandGenerator const& ccg,
                               const std::string& newline = "\n");
 
   /** Label to which to jump in a batch file after a failed step in a

+ 16 - 12
Source/cmMakefileTargetGenerator.cxx

@@ -21,6 +21,7 @@
 #include "cmTarget.h"
 #include "cmake.h"
 #include "cmComputeLinkInformation.h"
+#include "cmCustomCommandGenerator.h"
 #include "cmGeneratorExpression.h"
 
 #include "cmMakefileExecutableTargetGenerator.h"
@@ -158,11 +159,13 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
         si = customCommands.begin();
       si != customCommands.end(); ++si)
     {
-    cmCustomCommand const* cc = (*si)->GetCustomCommand();
-    this->GenerateCustomRuleFile(*cc);
+    cmCustomCommandGenerator ccg(*(*si)->GetCustomCommand(),
+                                 this->ConfigName,
+                                 this->Makefile);
+    this->GenerateCustomRuleFile(ccg);
     if (clean)
       {
-      const std::vector<std::string>& outputs = cc->GetOutputs();
+      const std::vector<std::string>& outputs = ccg.GetOutputs();
       for(std::vector<std::string>::const_iterator o = outputs.begin();
           o != outputs.end(); ++o)
         {
@@ -1178,7 +1181,8 @@ cmMakefileTargetGenerator
     {
     if(cmCustomCommand* cc = (*source)->GetCustomCommand())
       {
-      const std::vector<std::string>& outputs = cc->GetOutputs();
+      cmCustomCommandGenerator ccg(*cc, this->ConfigName, this->Makefile);
+      const std::vector<std::string>& outputs = ccg.GetOutputs();
       for(std::vector<std::string>::const_iterator o = outputs.begin();
           o != outputs.end(); ++o)
         {
@@ -1210,11 +1214,11 @@ void cmMakefileTargetGenerator
 
 //----------------------------------------------------------------------------
 void cmMakefileTargetGenerator
-::GenerateCustomRuleFile(const cmCustomCommand& cc)
+::GenerateCustomRuleFile(cmCustomCommandGenerator const& ccg)
 {
   // Collect the commands.
   std::vector<std::string> commands;
-  std::string comment = this->LocalGenerator->ConstructComment(cc);
+  std::string comment = this->LocalGenerator->ConstructComment(ccg);
   if(!comment.empty())
     {
     // add in a progress call if needed
@@ -1229,19 +1233,19 @@ void cmMakefileTargetGenerator
 
   // Now append the actual user-specified commands.
   cmOStringStream content;
-  this->LocalGenerator->AppendCustomCommand(commands, cc, this->Target, false,
+  this->LocalGenerator->AppendCustomCommand(commands, ccg, this->Target, false,
                                             cmLocalGenerator::HOME_OUTPUT,
                                             &content);
 
   // Collect the dependencies.
   std::vector<std::string> depends;
-  this->LocalGenerator->AppendCustomDepend(depends, cc);
+  this->LocalGenerator->AppendCustomDepend(depends, ccg);
 
   // Check whether we need to bother checking for a symbolic output.
   bool need_symbolic = this->GlobalGenerator->GetNeedSymbolicMark();
 
   // Write the rule.
-  const std::vector<std::string>& outputs = cc.GetOutputs();
+  const std::vector<std::string>& outputs = ccg.GetOutputs();
   std::vector<std::string>::const_iterator o = outputs.begin();
   {
   bool symbolic = false;
@@ -1259,7 +1263,7 @@ void cmMakefileTargetGenerator
   // If the rule has changed make sure the output is rebuilt.
   if(!symbolic)
     {
-    this->GlobalGenerator->AddRuleHash(cc.GetOutputs(), content.str());
+    this->GlobalGenerator->AddRuleHash(ccg.GetOutputs(), content.str());
     }
   }
 
@@ -1280,8 +1284,8 @@ void cmMakefileTargetGenerator
 
   // Setup implicit dependency scanning.
   for(cmCustomCommand::ImplicitDependsList::const_iterator
-        idi = cc.GetImplicitDepends().begin();
-      idi != cc.GetImplicitDepends().end(); ++idi)
+        idi = ccg.GetCC().GetImplicitDepends().begin();
+      idi != ccg.GetCC().GetImplicitDepends().end(); ++idi)
     {
     std::string objFullPath =
       this->Convert(outputs[0], cmLocalGenerator::FULL);

+ 2 - 2
Source/cmMakefileTargetGenerator.h

@@ -15,7 +15,7 @@
 #include "cmLocalUnixMakefileGenerator3.h"
 #include "cmOSXBundleGenerator.h"
 
-class cmCustomCommand;
+class cmCustomCommandGenerator;
 class cmDependInformation;
 class cmDepends;
 class cmGeneratorTarget;
@@ -102,7 +102,7 @@ protected:
                               std::vector<std::string>& depends);
 
   // write the build rule for a custom command
-  void GenerateCustomRuleFile(const cmCustomCommand& cc);
+  void GenerateCustomRuleFile(cmCustomCommandGenerator const& ccg);
 
   // write a rule to drive building of more than one output from
   // another rule

+ 4 - 1
Source/cmNinjaNormalTargetGenerator.cxx

@@ -18,6 +18,7 @@
 #include "cmMakefile.h"
 #include "cmOSXBundleGenerator.h"
 #include "cmGeneratorTarget.h"
+#include "cmCustomCommandGenerator.h"
 
 #include <assert.h>
 #include <algorithm>
@@ -555,7 +556,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
     for (std::vector<cmCustomCommand>::const_iterator
          ci = cmdLists[i]->begin();
          ci != cmdLists[i]->end(); ++ci) {
-      this->GetLocalGenerator()->AppendCustomCommandLines(&*ci,
+      cmCustomCommandGenerator ccg(*ci, this->GetConfigName(),
+                                   this->GetMakefile());
+      this->GetLocalGenerator()->AppendCustomCommandLines(ccg,
                                                           *cmdLineLists[i]);
     }
   }

+ 3 - 1
Source/cmNinjaTargetGenerator.cxx

@@ -577,7 +577,9 @@ cmNinjaTargetGenerator
       si != customCommands.end(); ++si)
     {
     cmCustomCommand const* cc = (*si)->GetCustomCommand();
-    const std::vector<std::string>& ccoutputs = cc->GetOutputs();
+    cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
+                                 this->GetMakefile());
+    const std::vector<std::string>& ccoutputs = ccg.GetOutputs();
     std::transform(ccoutputs.begin(), ccoutputs.end(),
                    std::back_inserter(orderOnlyDeps), MapToNinjaPath());
     }

+ 8 - 3
Source/cmNinjaUtilityTargetGenerator.cxx

@@ -17,6 +17,7 @@
 #include "cmMakefile.h"
 #include "cmSourceFile.h"
 #include "cmTarget.h"
+#include "cmCustomCommandGenerator.h"
 
 cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(
     cmGeneratorTarget *target)
@@ -37,8 +38,10 @@ void cmNinjaUtilityTargetGenerator::Generate()
   for (unsigned i = 0; i != 2; ++i) {
     for (std::vector<cmCustomCommand>::const_iterator
          ci = cmdLists[i]->begin(); ci != cmdLists[i]->end(); ++ci) {
-      this->GetLocalGenerator()->AppendCustomCommandDeps(&*ci, deps);
-      this->GetLocalGenerator()->AppendCustomCommandLines(&*ci, commands);
+      cmCustomCommandGenerator ccg(*ci, this->GetConfigName(),
+                                   this->GetMakefile());
+      this->GetLocalGenerator()->AppendCustomCommandDeps(ccg, deps);
+      this->GetLocalGenerator()->AppendCustomCommandLines(ccg, commands);
     }
   }
 
@@ -49,10 +52,12 @@ void cmNinjaUtilityTargetGenerator::Generate()
     {
     if(cmCustomCommand* cc = (*source)->GetCustomCommand())
       {
+      cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
+                                   this->GetMakefile());
       this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
 
       // Depend on all custom command outputs.
-      const std::vector<std::string>& ccOutputs = cc->GetOutputs();
+      const std::vector<std::string>& ccOutputs = ccg.GetOutputs();
       std::transform(ccOutputs.begin(), ccOutputs.end(),
                      std::back_inserter(deps), MapToNinjaPath());
       }

+ 12 - 11
Source/cmVisualStudio10TargetGenerator.cxx

@@ -19,6 +19,7 @@
 #include "cmSourceFile.h"
 #include "cmVisualStudioGeneratorOptions.h"
 #include "cmLocalVisualStudio7Generator.h"
+#include "cmCustomCommandGenerator.h"
 #include "cmVS10CLFlagTable.h"
 #include "cmVS10LinkFlagTable.h"
 #include "cmVS10LibFlagTable.h"
@@ -616,8 +617,6 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
       }
     }
   cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
-  std::string comment = lg->ConstructComment(command);
-  comment = cmVS10EscapeComment(comment);
   std::vector<std::string> *configs =
     static_cast<cmGlobalVisualStudio7Generator *>
     (this->GlobalGenerator)->GetConfigurations();
@@ -627,8 +626,11 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
   for(std::vector<std::string>::iterator i = configs->begin();
       i != configs->end(); ++i)
     {
+    cmCustomCommandGenerator ccg(command, *i, this->Makefile);
+    std::string comment = lg->ConstructComment(ccg);
+    comment = cmVS10EscapeComment(comment);
     std::string script =
-      cmVS10EscapeXML(lg->ConstructScript(command, i->c_str()));
+      cmVS10EscapeXML(lg->ConstructScript(ccg));
     this->WritePlatformConfigTag("Message",i->c_str(), 3);
     (*this->BuildFileStream ) << cmVS10EscapeXML(comment) << "</Message>\n";
     this->WritePlatformConfigTag("Command", i->c_str(), 3);
@@ -637,8 +639,8 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
 
     (*this->BuildFileStream ) << source->GetFullPath();
     for(std::vector<std::string>::const_iterator d =
-          command.GetDepends().begin();
-        d != command.GetDepends().end();
+          ccg.GetDepends().begin();
+        d != ccg.GetDepends().end();
         ++d)
       {
       std::string dep;
@@ -652,8 +654,8 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source,
     this->WritePlatformConfigTag("Outputs", i->c_str(), 3);
     const char* sep = "";
     for(std::vector<std::string>::const_iterator o =
-          command.GetOutputs().begin();
-        o != command.GetOutputs().end();
+          ccg.GetOutputs().begin();
+        o != ccg.GetOutputs().end();
         ++o)
       {
       std::string out = *o;
@@ -1835,13 +1837,12 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
   for(std::vector<cmCustomCommand>::const_iterator i = commands.begin();
       i != commands.end(); ++i)
     {
-    const cmCustomCommand& command = *i;
+    cmCustomCommandGenerator ccg(*i, configName, this->Makefile);
     comment += pre;
-    comment += lg->ConstructComment(command);
+    comment += lg->ConstructComment(ccg);
     script += pre;
     pre = "\n";
-    script +=
-      cmVS10EscapeXML(lg->ConstructScript(command, configName.c_str()));
+    script += cmVS10EscapeXML(lg->ConstructScript(ccg));
     }
   comment = cmVS10EscapeComment(comment);
   this->WriteString("<Message>",3);