Kaynağa Gözat

ENH: Implemented VT100 terminal escape sequences. If CMAKE_COLOR_MAKEFILE is set then messages produced by makefiles will be in color if the native tool supports it. This addresses bug#3060.

Brad King 19 yıl önce
ebeveyn
işleme
eb31755eb2

+ 1 - 0
Source/cmGlobalBorlandMakefileGenerator.cxx

@@ -24,6 +24,7 @@ cmGlobalBorlandMakefileGenerator::cmGlobalBorlandMakefileGenerator()
   this->EmptyRuleHackDepends = "NUL";
   this->FindMakeProgramFile = "CMakeBorlandFindMake.cmake";
   this->ForceUnixPaths = false;
+  this->ToolSupportsColorVT100 = false;
 }
 
 

+ 3 - 0
Source/cmGlobalGenerator.cxx

@@ -33,6 +33,9 @@ cmGlobalGenerator::cmGlobalGenerator()
 {
   // by default use the native paths
   this->ForceUnixPaths = false;
+
+  // By default do not try to support color.
+  this->ToolSupportsColorVT100 = false;
 }
 
 cmGlobalGenerator::~cmGlobalGenerator()

+ 2 - 0
Source/cmGlobalGenerator.h

@@ -127,6 +127,7 @@ public:
   static int s_TryCompileTimeout;
   
   bool GetForceUnixPaths() {return this->ForceUnixPaths;}
+  bool GetToolSupportsColorVT100() { return this->ToolSupportsColorVT100; }
   ///! return the language for the given extension
   const char* GetLanguageFromExtension(const char* ext);
   ///! is an extension to be ignored
@@ -193,6 +194,7 @@ protected:
   virtual const char* GetRebuildCacheTargetName() { return 0; }
 
   bool ForceUnixPaths;
+  bool ToolSupportsColorVT100;
   cmStdString FindMakeProgramFile;
   cmStdString ConfiguredFilesPath;
   cmake *CMakeInstance;

+ 1 - 0
Source/cmGlobalKdevelopGenerator.cxx

@@ -28,6 +28,7 @@ cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator()
   // This type of makefile always requires unix style paths
   this->ForceUnixPaths = true;
   this->FindMakeProgramFile = "CMakeUnixFindMake.cmake";
+  this->ToolSupportsColorVT100 = false;
 }
 
 ///! Create a local generator appropriate to this Global Generator

+ 1 - 0
Source/cmGlobalMSYSMakefileGenerator.cxx

@@ -23,6 +23,7 @@ cmGlobalMSYSMakefileGenerator::cmGlobalMSYSMakefileGenerator()
 {
   this->FindMakeProgramFile = "CMakeMSYSFindMake.cmake";
   this->ForceUnixPaths = true;
+  this->ToolSupportsColorVT100 = true;
 }
 
 std::string 

+ 1 - 1
Source/cmGlobalMinGWMakefileGenerator.cxx

@@ -22,7 +22,7 @@ cmGlobalMinGWMakefileGenerator::cmGlobalMinGWMakefileGenerator()
 {
   this->FindMakeProgramFile = "CMakeMinGWFindMake.cmake";
   this->ForceUnixPaths = true;
-  
+  this->ToolSupportsColorVT100 = false;
 }
 
 void cmGlobalMinGWMakefileGenerator::EnableLanguage(std::vector<std::string>const& l,

+ 1 - 0
Source/cmGlobalNMakeMakefileGenerator.cxx

@@ -22,6 +22,7 @@ cmGlobalNMakeMakefileGenerator::cmGlobalNMakeMakefileGenerator()
 {
   this->FindMakeProgramFile = "CMakeNMakeFindMake.cmake";
   this->ForceUnixPaths = false;
+  this->ToolSupportsColorVT100 = false;
 }
 
 void cmGlobalNMakeMakefileGenerator::EnableLanguage(std::vector<std::string>const& l,

+ 1 - 0
Source/cmGlobalUnixMakefileGenerator3.cxx

@@ -26,6 +26,7 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
   // This type of makefile always requires unix style paths
   this->ForceUnixPaths = true;
   this->FindMakeProgramFile = "CMakeUnixFindMake.cmake";
+  this->ToolSupportsColorVT100 = true;
 }
 
 void cmGlobalUnixMakefileGenerator3

+ 1 - 0
Source/cmGlobalWatcomWMakeGenerator.cxx

@@ -22,6 +22,7 @@ cmGlobalWatcomWMakeGenerator::cmGlobalWatcomWMakeGenerator()
 {
   this->FindMakeProgramFile = "CMakeFindWMake.cmake";
   this->ForceUnixPaths = false;
+  this->ToolSupportsColorVT100 = false;
 }
 
 void cmGlobalWatcomWMakeGenerator::EnableLanguage(std::vector<std::string>const& l,

+ 62 - 2
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -35,6 +35,28 @@
 #include <memory> // auto_ptr
 #include <queue>
 
+#define CMAKE_VT100_NORMAL        "\33[0m"
+#define CMAKE_VT100_BOLD          "\33[1m"
+#define CMAKE_VT100_UNDERLINE     "\33[4m"
+#define CMAKE_VT100_BLINK         "\33[5m"
+#define CMAKE_VT100_INVERSE       "\33[7m"
+#define CMAKE_VT100_FRONT_BLACK   "\33[30m"
+#define CMAKE_VT100_FRONT_RED     "\33[31m"
+#define CMAKE_VT100_FRONT_GREEN   "\33[32m"
+#define CMAKE_VT100_FRONT_YELLOW  "\33[33m"
+#define CMAKE_VT100_FRONT_BLUE    "\33[34m"
+#define CMAKE_VT100_FRONT_MAGENTA "\33[35m"
+#define CMAKE_VT100_FRONT_CYAN    "\33[36m"
+#define CMAKE_VT100_FRONT_WHITE   "\33[37m"
+#define CMAKE_VT100_BACK_BLACK    "\33[40m"
+#define CMAKE_VT100_BACK_RED      "\33[41m"
+#define CMAKE_VT100_BACK_GREEN    "\33[42m"
+#define CMAKE_VT100_BACK_YELLOW   "\33[43m"
+#define CMAKE_VT100_BACK_BLUE     "\33[44m"
+#define CMAKE_VT100_BACK_MAGENTA  "\33[45m"
+#define CMAKE_VT100_BACK_CYAN     "\33[46m"
+#define CMAKE_VT100_BACK_WHITE    "\33[47m"
+
 //----------------------------------------------------------------------------
 cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3()
 {
@@ -851,8 +873,37 @@ cmLocalUnixMakefileGenerator3
 //----------------------------------------------------------------------------
 void
 cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands,
-                                          const char* text)
+                                          const char* text,
+                                          EchoColor color)
 {
+  // Choose the color for the text.
+  const char* prefix = 0;
+  if(this->GlobalGenerator->GetToolSupportsColorVT100() &&
+     this->Makefile->IsOn("CMAKE_COLOR_MAKEFILE"))
+    {
+    switch(color)
+      {
+      case EchoNormal:
+        break;
+      case EchoDepend:
+        prefix = CMAKE_VT100_FRONT_MAGENTA CMAKE_VT100_BOLD;
+        break;
+      case EchoBuild:
+        prefix = CMAKE_VT100_FRONT_GREEN CMAKE_VT100_BOLD;
+        break;
+      case EchoLink:
+        prefix = CMAKE_VT100_FRONT_YELLOW CMAKE_VT100_BOLD;
+        break;
+      case EchoGenerate:
+        prefix = CMAKE_VT100_FRONT_BLUE CMAKE_VT100_BOLD;
+        break;
+      case EchoGlobal:
+        prefix = CMAKE_VT100_FRONT_CYAN CMAKE_VT100_BOLD;
+        break;
+      }
+    }
+  const char* suffix = prefix? CMAKE_VT100_NORMAL : 0;
+
   // Echo one line at a time.
   std::string line;
   for(const char* c = text;; ++c)
@@ -868,7 +919,15 @@ cmLocalUnixMakefileGenerator3::AppendEcho(std::vector<std::string>& commands,
           {
           cmd += "\"";
           }
+        if(prefix)
+          {
+          cmd += prefix;
+          }
         cmd += line;
+        if(suffix)
+          {
+          cmd += suffix;
+          }
         if(this->EchoNeedsQuote)
           {
           cmd += "\"";
@@ -1320,7 +1379,8 @@ void cmLocalUnixMakefileGenerator3
         {
         depends.push_back(dit->c_str());
         }
-      this->AppendEcho(commands, text);
+      this->AppendEcho(commands, text,
+                       cmLocalUnixMakefileGenerator3::EchoGlobal);
 
       // Utility targets store their rules in pre- and post-build commands.
       this->AppendCustomDepends(depends,   

+ 4 - 1
Source/cmLocalUnixMakefileGenerator3.h

@@ -152,7 +152,10 @@ public:
   std::string GetRecursiveMakeCall(const char *makefile, const char* tgt);    
   
   // append an echo command
-  void AppendEcho(std::vector<std::string>& commands, const char* text);
+  enum EchoColor { EchoNormal, EchoDepend, EchoBuild, EchoLink,
+                   EchoGenerate, EchoGlobal };
+  void AppendEcho(std::vector<std::string>& commands, const char* text,
+                  EchoColor color = EchoNormal);
 
   static std::string GetTargetDirectory(cmTarget& target);
 

+ 2 - 1
Source/cmMakefileExecutableTargetGenerator.cxx

@@ -196,7 +196,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
   buildEcho += linkLanguage;
   buildEcho += " executable ";
   buildEcho += targetOutPath;
-  this->LocalGenerator->AppendEcho(commands, buildEcho.c_str());
+  this->LocalGenerator->AppendEcho(commands, buildEcho.c_str(),
+                                   cmLocalUnixMakefileGenerator3::EchoLink);
 
   // Build a list of compiler flags and linker flags.
   std::string flags;

+ 2 - 1
Source/cmMakefileLibraryTargetGenerator.cxx

@@ -265,7 +265,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
       break;
     }
   buildEcho += targetOutPath.c_str();
-  this->LocalGenerator->AppendEcho(commands, buildEcho.c_str());
+  this->LocalGenerator->AppendEcho(commands, buildEcho.c_str(),
+                                   cmLocalUnixMakefileGenerator3::EchoLink);
 
   // Construct a list of files associated with this library that may
   // need to be cleaned.

+ 7 - 3
Source/cmMakefileTargetGenerator.cxx

@@ -374,7 +374,8 @@ cmMakefileTargetGenerator
   buildEcho += lang;
   buildEcho += " object ";
   buildEcho += relativeObj;
-  this->LocalGenerator->AppendEcho(commands, buildEcho.c_str());
+  this->LocalGenerator->AppendEcho(commands, buildEcho.c_str(),
+                                   cmLocalUnixMakefileGenerator3::EchoBuild);
 
   // Construct the compile rules.
   std::string compileRuleVar = "CMAKE_";
@@ -540,7 +541,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
   // Write the dependency generation rule.
   std::string depEcho = "Scanning dependencies of target ";
   depEcho += this->Target->GetName();
-  this->LocalGenerator->AppendEcho(commands, depEcho.c_str());
+  this->LocalGenerator->AppendEcho(commands, depEcho.c_str(),
+                                   cmLocalUnixMakefileGenerator3::EchoDepend);
   
   // Add a command to call CMake to scan dependencies.  CMake will
   // touch the corresponding depends file after scanning dependencies.
@@ -627,7 +629,9 @@ void cmMakefileTargetGenerator
   std::vector<std::string> commands;
   std::string preEcho = "Generating ";
   preEcho += output;
-  this->LocalGenerator->AppendEcho(commands, preEcho.c_str());
+  this->LocalGenerator
+    ->AppendEcho(commands, preEcho.c_str(),
+                 cmLocalUnixMakefileGenerator3::EchoGenerate);
   this->LocalGenerator->AppendCustomCommand(commands, cc);
   
   // Collect the dependencies.