Hi all,

This patch exposes the Ninja console pool feature via the add_custom_command
and add_custom_target commands. Specifically, it introduces a USE_CONSOLE
flag which can be used to communicate to the generator that the command
would prefer to use the console. It has no effect on generators other than
the Ninja generator.

The patch also causes the feature to be used with the built-in cache editor.

Docs/tests to come. Any comments on the proposed approach are appreciated.

Thanks,
-- 
Peter
>From eaebc04718f1a96c59ac03d21ebb4bb95db4475f Mon Sep 17 00:00:00 2001
From: Peter Collingbourne <pe...@pcc.me.uk>
Date: Tue, 4 Nov 2014 00:05:51 +0100
Subject: [PATCH] console pools

---
 Source/cmAddCustomCommandCommand.cxx     |  9 +++++++--
 Source/cmAddCustomTargetCommand.cxx      | 13 ++++++++++---
 Source/cmCustomCommand.cxx               | 16 +++++++++++++++-
 Source/cmCustomCommand.h                 |  6 ++++++
 Source/cmGlobalGenerator.cxx             | 25 +++++++++++++------------
 Source/cmGlobalGenerator.h               |  3 ++-
 Source/cmGlobalNinjaGenerator.cxx        | 16 +++++++++++++---
 Source/cmGlobalNinjaGenerator.h          |  4 ++++
 Source/cmLocalNinjaGenerator.cxx         |  1 +
 Source/cmMakefile.cxx                    | 18 ++++++++++++------
 Source/cmMakefile.h                      | 12 ++++++++----
 Source/cmNinjaTargetGenerator.h          |  1 -
 Source/cmNinjaUtilityTargetGenerator.cxx |  5 +++++
 13 files changed, 96 insertions(+), 33 deletions(-)

diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 2d19610..e035195 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -35,6 +35,7 @@ bool cmAddCustomCommandCommand
   std::vector<std::string> depends, outputs, output;
   bool verbatim = false;
   bool append = false;
+  bool console = false;
   std::string implicit_depends_lang;
   cmCustomCommand::ImplicitDependsList implicit_depends;
 
@@ -102,6 +103,10 @@ bool cmAddCustomCommandCommand
       {
       append = true;
       }
+    else if(copy == "USE_CONSOLE")
+      {
+      console = true;
+      }
     else if(copy == "TARGET")
       {
       doing = doing_target;
@@ -312,7 +317,7 @@ bool cmAddCustomCommandCommand
     this->Makefile->AddCustomCommandToTarget(target, no_depends,
                                              commandLines, cctype,
                                              comment, working.c_str(),
-                                             escapeOldStyle);
+                                             escapeOldStyle, console);
     }
   else if(target.empty())
     {
@@ -321,7 +326,7 @@ bool cmAddCustomCommandCommand
                                              main_dependency,
                                              commandLines, comment,
                                              working.c_str(), false,
-                                             escapeOldStyle);
+                                             escapeOldStyle, console);
 
     // Add implicit dependency scanning requests if any were given.
     if(!implicit_depends.empty())
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index 3235502..2d4ad48 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -48,6 +48,7 @@ bool cmAddCustomTargetCommand
   std::vector<std::string> depends;
   std::string working_directory;
   bool verbatim = false;
+  bool console = false;
   std::string comment_buffer;
   const char* comment = 0;
   std::vector<std::string> sources;
@@ -59,7 +60,7 @@ bool cmAddCustomTargetCommand
     doing_working_directory,
     doing_comment,
     doing_source,
-    doing_verbatim
+    doing_nothing
   };
   tdoing doing = doing_command;
 
@@ -90,9 +91,14 @@ bool cmAddCustomTargetCommand
       }
     else if(copy == "VERBATIM")
       {
-      doing = doing_verbatim;
+      doing = doing_nothing;
       verbatim = true;
       }
+    else if(copy == "USE_CONSOLE")
+      {
+      doing = doing_nothing;
+      console = true;
+      }
     else if (copy == "COMMENT")
       {
       doing = doing_comment;
@@ -226,7 +232,8 @@ bool cmAddCustomTargetCommand
   cmTarget* target =
     this->Makefile->AddUtilityCommand(targetName, excludeFromAll,
                                       working_directory.c_str(), depends,
-                                      commandLines, escapeOldStyle, comment);
+                                      commandLines, escapeOldStyle, comment,
+                                      console);
 
   // Add additional user-specified source files to the target.
   target->AddSources(sources);
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
index c161eb6..46d3cf5 100644
--- a/Source/cmCustomCommand.cxx
+++ b/Source/cmCustomCommand.cxx
@@ -34,7 +34,8 @@ cmCustomCommand::cmCustomCommand(const cmCustomCommand& r):
   WorkingDirectory(r.WorkingDirectory),
   EscapeAllowMakeVars(r.EscapeAllowMakeVars),
   EscapeOldStyle(r.EscapeOldStyle),
-  Backtrace(r.Backtrace)
+  Backtrace(r.Backtrace),
+  Console(r.Console)
 {
 }
 
@@ -56,6 +57,7 @@ cmCustomCommand& cmCustomCommand::operator=(cmCustomCommand const& r)
   this->EscapeOldStyle = r.EscapeOldStyle;
   this->ImplicitDepends = r.ImplicitDepends;
   this->Backtrace = r.Backtrace;
+  this->Console = r.Console;
 
   return *this;
 }
@@ -184,3 +186,15 @@ void cmCustomCommand::AppendImplicitDepends(ImplicitDependsList const& l)
   this->ImplicitDepends.insert(this->ImplicitDepends.end(),
                                l.begin(), l.end());
 }
+
+//----------------------------------------------------------------------------
+bool cmCustomCommand::GetConsole() const
+{
+  return this->Console;
+}
+
+//----------------------------------------------------------------------------
+void cmCustomCommand::SetConsole(bool b)
+{
+  this->Console = b;
+}
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
index 21dbefb..25baf69 100644
--- a/Source/cmCustomCommand.h
+++ b/Source/cmCustomCommand.h
@@ -79,6 +79,11 @@ public:
   void AppendImplicitDepends(ImplicitDependsList const&);
   ImplicitDependsList const& GetImplicitDepends() const;
 
+  /** Set/Get whether this custom command should be given access to the
+      real console (if possible).  */
+  bool GetConsole() const;
+  void SetConsole(bool b);
+
 private:
   std::vector<std::string> Outputs;
   std::vector<std::string> Depends;
@@ -90,6 +95,7 @@ private:
   bool EscapeOldStyle;
   cmListFileBacktrace Backtrace;
   ImplicitDependsList ImplicitDepends;
+  bool Console;
 };
 
 #endif
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index a729c3d..7f9028d 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -2197,7 +2197,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
       = this->CreateGlobalTarget(this->GetPackageTargetName(),
                                  "Run CPack packaging tool...",
                                  &cpackCommandLines, depends,
-                                 workingDir.c_str());
+                                 workingDir.c_str(), /*console*/false);
     }
   // CPack source
   const char* packageSourceTargetName = this->GetPackageSourceTargetName();
@@ -2221,8 +2221,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
         = this->CreateGlobalTarget(packageSourceTargetName,
                                    "Run CPack packaging tool for source...",
                                    &cpackCommandLines, depends,
-                                   workingDir.c_str()
-                                   );
+                                   workingDir.c_str(), /*console*/false);
       }
     }
 
@@ -2247,7 +2246,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
     cpackCommandLines.push_back(singleLine);
     (*targets)[this->GetTestTargetName()]
       = this->CreateGlobalTarget(this->GetTestTargetName(),
-        "Running tests...", &cpackCommandLines, depends, 0);
+        "Running tests...", &cpackCommandLines, depends, 0, /*console*/false);
     }
 
   //Edit Cache
@@ -2270,7 +2269,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
       (*targets)[editCacheTargetName] =
         this->CreateGlobalTarget(
           editCacheTargetName, "Running CMake cache editor...",
-          &cpackCommandLines, depends, 0);
+          &cpackCommandLines, depends, 0, /*console*/true);
       }
     else
       {
@@ -2283,7 +2282,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
         this->CreateGlobalTarget(
           editCacheTargetName,
           "No interactive CMake dialog available...",
-          &cpackCommandLines, depends, 0);
+          &cpackCommandLines, depends, 0, /*console*/false);
       }
     }
 
@@ -2302,7 +2301,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
     (*targets)[rebuildCacheTargetName] =
       this->CreateGlobalTarget(
         rebuildCacheTargetName, "Running CMake to regenerate build system...",
-        &cpackCommandLines, depends, 0);
+        &cpackCommandLines, depends, 0, /*console*/false);
     }
 
   //Install
@@ -2342,7 +2341,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
       (*targets)["list_install_components"]
         = this->CreateGlobalTarget("list_install_components",
           ostr.str().c_str(),
-          &cpackCommandLines, depends, 0);
+          &cpackCommandLines, depends, 0, /*console*/false);
       }
     std::string cmd = cmakeCommand;
     cpackCommandLines.erase(cpackCommandLines.begin(),
@@ -2382,7 +2381,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
     (*targets)[this->GetInstallTargetName()] =
       this->CreateGlobalTarget(
         this->GetInstallTargetName(), "Install the project...",
-        &cpackCommandLines, depends, 0);
+        &cpackCommandLines, depends, 0, /*console*/false);
 
     // install_local
     if(const char* install_local = this->GetInstallLocalTargetName())
@@ -2398,7 +2397,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
       (*targets)[install_local] =
         this->CreateGlobalTarget(
           install_local, "Installing only the local directory...",
-          &cpackCommandLines, depends, 0);
+          &cpackCommandLines, depends, 0, /*console*/false);
       }
 
     // install_strip
@@ -2415,7 +2414,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
       (*targets)[install_strip] =
         this->CreateGlobalTarget(
           install_strip, "Installing the project stripped...",
-          &cpackCommandLines, depends, 0);
+          &cpackCommandLines, depends, 0, /*console*/false);
       }
     }
 }
@@ -2489,7 +2488,8 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(
   const std::string& name, const char* message,
   const cmCustomCommandLines* commandLines,
   std::vector<std::string> depends,
-  const char* workingDirectory)
+  const char* workingDirectory,
+  bool console)
 {
   // Package
   cmTarget target;
@@ -2502,6 +2502,7 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(
   // Store the custom command in the target.
   cmCustomCommand cc(0, no_outputs, no_depends, *commandLines, 0,
                      workingDirectory);
+  cc.SetConsole(console);
   target.AddPostBuildCommand(cc);
   target.SetProperty("EchoString", message);
   std::vector<std::string>::iterator dit;
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index ddd7e91..c506a72 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -378,7 +378,8 @@ protected:
   void CreateDefaultGlobalTargets(cmTargets* targets);
   cmTarget CreateGlobalTarget(const std::string& name, const char* message,
     const cmCustomCommandLines* commandLines,
-    std::vector<std::string> depends, const char* workingDir);
+    std::vector<std::string> depends, const char* workingDir,
+    bool console);
 
   bool NeedSymbolicMark;
   bool UseLinkScript;
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 498ae9a..888d516 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -250,6 +250,7 @@ void
 cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command,
                                                 const std::string& description,
                                                 const std::string& comment,
+                                                bool console,
                                                 const cmNinjaDeps& outputs,
                                                 const cmNinjaDeps& deps,
                                                 const cmNinjaDeps& orderOnly)
@@ -266,6 +267,10 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command,
   cmNinjaVars vars;
   vars["COMMAND"] = cmd;
   vars["DESC"] = EncodeLiteral(description);
+  if (console && SupportsConsolePool())
+    {
+    vars["pool"] = "console";
+    }
 
   this->WriteBuild(*this->BuildFileStream,
                    comment,
@@ -826,6 +831,7 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies()
     std::copy(i->second.begin(), i->second.end(), std::back_inserter(deps));
     WriteCustomCommandBuild(/*command=*/"", /*description=*/"",
                             "Assume dependencies for generated source file.",
+                            /*console*/false,
                             cmNinjaDeps(1, i->first), deps);
   }
 }
@@ -1141,9 +1147,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
   cmNinjaVars variables;
   // Use 'console' pool to get non buffered output of the CMake re-run call
   // Available since Ninja 1.5
-  if(cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
-                                   ninjaVersion().c_str(),
-                                   "1.5") == false)
+  if(SupportsConsolePool())
     {
     variables["pool"] = "console";
     }
@@ -1185,6 +1189,12 @@ std::string cmGlobalNinjaGenerator::ninjaVersion() const
   return version;
 }
 
+bool cmGlobalNinjaGenerator::SupportsConsolePool() const
+{
+  return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
+                                       ninjaVersion().c_str(), "1.5") == false;
+}
+
 void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
 {
   WriteRule(*this->RulesFileStream,
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index f666ee3..0547aae 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -103,6 +103,7 @@ public:
   void WriteCustomCommandBuild(const std::string& command,
                                const std::string& description,
                                const std::string& comment,
+                               bool console,
                                const cmNinjaDeps& outputs,
                                const cmNinjaDeps& deps = cmNinjaDeps(),
                                const cmNinjaDeps& orderOnly = cmNinjaDeps());
@@ -299,6 +300,9 @@ public:
   virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
 
   std::string ninjaVersion() const;
+
+  bool SupportsConsolePool() const;
+
 protected:
 
   /// Overloaded methods. @see cmGlobalGenerator::Generate()
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 9225f64..301a9e0 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -468,6 +468,7 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
       this->BuildCommandLine(cmdLines),
       this->ConstructComment(ccg),
       "Custom command for " + ninjaOutputs[0],
+      cc->GetConsole(),
       ninjaOutputs,
       ninjaDeps,
       orderOnlyDeps);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 8a8aadc..a19f7bc 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -885,7 +885,8 @@ cmMakefile::AddCustomCommandToTarget(const std::string& target,
                                      cmTarget::CustomCommandType type,
                                      const char* comment,
                                      const char* workingDir,
-                                     bool escapeOldStyle) const
+                                     bool escapeOldStyle,
+                                     bool console) const
 {
   // Find the target to which to add the custom command.
   cmTargets::iterator ti = this->Targets.find(target);
@@ -941,6 +942,7 @@ cmMakefile::AddCustomCommandToTarget(const std::string& target,
                      commandLines, comment, workingDir);
   cc.SetEscapeOldStyle(escapeOldStyle);
   cc.SetEscapeAllowMakeVars(true);
+  cc.SetConsole(console);
   switch(type)
     {
     case cmTarget::PRE_BUILD:
@@ -964,7 +966,8 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
                                      const char* comment,
                                      const char* workingDir,
                                      bool replace,
-                                     bool escapeOldStyle)
+                                     bool escapeOldStyle,
+                                     bool console)
 {
   // Make sure there is at least one output.
   if(outputs.empty())
@@ -1071,6 +1074,7 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
                           comment, workingDir);
     cc->SetEscapeOldStyle(escapeOldStyle);
     cc->SetEscapeAllowMakeVars(true);
+    cc->SetConsole(console);
     file->SetCustomCommand(cc);
     this->UpdateOutputToSourceMap(outputs, file);
     }
@@ -1119,13 +1123,14 @@ cmMakefile::AddCustomCommandToOutput(const std::string& output,
                                      const char* comment,
                                      const char* workingDir,
                                      bool replace,
-                                     bool escapeOldStyle)
+                                     bool escapeOldStyle,
+                                     bool console)
 {
   std::vector<std::string> outputs;
   outputs.push_back(output);
   return this->AddCustomCommandToOutput(outputs, depends, main_dependency,
                                         commandLines, comment, workingDir,
-                                        replace, escapeOldStyle);
+                                        replace, escapeOldStyle, console);
 }
 
 //----------------------------------------------------------------------------
@@ -1242,7 +1247,8 @@ cmMakefile::AddUtilityCommand(const std::string& utilityName,
                               const char* workingDirectory,
                               const std::vector<std::string>& depends,
                               const cmCustomCommandLines& commandLines,
-                              bool escapeOldStyle, const char* comment)
+                              bool escapeOldStyle, const char* comment,
+                              bool console)
 {
   // Create a target instance for this utility.
   cmTarget* target = this->AddNewTarget(cmTarget::UTILITY, utilityName);
@@ -1269,7 +1275,7 @@ cmMakefile::AddUtilityCommand(const std::string& utilityName,
                                    no_main_dependency,
                                    commandLines, comment,
                                    workingDirectory, no_replace,
-                                   escapeOldStyle);
+                                   escapeOldStyle, console);
     cmSourceFile* sf = target->AddSourceCMP0049(force);
 
     // The output is not actually created so mark it symbolic.
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 824513b..f4fc50a 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -174,7 +174,8 @@ public:
                                 const cmCustomCommandLines& commandLines,
                                 cmTarget::CustomCommandType type,
                                 const char* comment, const char* workingDir,
-                                bool escapeOldStyle = true) const;
+                                bool escapeOldStyle = true,
+                                bool console = false) const;
   cmSourceFile* AddCustomCommandToOutput(
     const std::vector<std::string>& outputs,
     const std::vector<std::string>& depends,
@@ -182,7 +183,8 @@ public:
     const cmCustomCommandLines& commandLines,
     const char* comment, const char* workingDir,
     bool replace = false,
-    bool escapeOldStyle = true);
+    bool escapeOldStyle = true,
+    bool console = false);
   cmSourceFile* AddCustomCommandToOutput(
     const std::string& output,
     const std::vector<std::string>& depends,
@@ -190,7 +192,8 @@ public:
     const cmCustomCommandLines& commandLines,
     const char* comment, const char* workingDir,
     bool replace = false,
-    bool escapeOldStyle = true);
+    bool escapeOldStyle = true,
+    bool console = false);
   void AddCustomCommandOldStyle(const std::string& target,
                                 const std::vector<std::string>& outputs,
                                 const std::vector<std::string>& depends,
@@ -237,7 +240,8 @@ public:
                               const std::vector<std::string>& depends,
                               const cmCustomCommandLines& commandLines,
                               bool escapeOldStyle = true,
-                              const char* comment = 0);
+                              const char* comment = 0,
+                              bool console = false);
 
   /**
    * Add a link library to the build.
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 40a15a3..17cf517 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -116,7 +116,6 @@ protected:
   void WriteObjectBuildStatements();
   void WriteObjectBuildStatement(cmSourceFile const* source,
                                  bool writeOrderDependsTargetForTarget);
-  void WriteCustomCommandBuildStatement(cmCustomCommand *cc);
 
   cmNinjaDeps GetObjects() const
   { return this->Objects; }
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index f5d18dc..f9ad710 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -35,6 +35,8 @@ void cmNinjaUtilityTargetGenerator::Generate()
     &this->GetTarget()->GetPostBuildCommands()
   };
 
+  bool console = false;
+
   for (unsigned i = 0; i != 2; ++i) {
     for (std::vector<cmCustomCommand>::const_iterator
          ci = cmdLists[i]->begin(); ci != cmdLists[i]->end(); ++ci) {
@@ -42,6 +44,8 @@ void cmNinjaUtilityTargetGenerator::Generate()
                                    this->GetMakefile());
       this->GetLocalGenerator()->AppendCustomCommandDeps(ccg, deps);
       this->GetLocalGenerator()->AppendCustomCommandLines(ccg, commands);
+      if (ci->GetConsole())
+        console = true;
     }
   }
 
@@ -110,6 +114,7 @@ void cmNinjaUtilityTargetGenerator::Generate()
       command,
       desc,
       "Utility command for " + this->GetTargetName(),
+      console,
       cmNinjaDeps(1, utilCommandName),
       deps);
 
-- 
1.8.4.rc3

-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake-developers

Reply via email to