1
0
Эх сурвалжийг харах

BUG: changed to progress to make it more flexible and to no relink targets as often

Ken Martin 19 жил өмнө
parent
commit
f1dfa7e78f

+ 68 - 76
Source/cmGlobalUnixMakefileGenerator3.cxx

@@ -29,8 +29,6 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
   this->ForceUnixPaths = true;
   this->FindMakeProgramFile = "CMakeUnixFindMake.cmake";
   this->ToolSupportsColor = true;
-  this->NumberOfSourceFiles = 0;
-  this->NumberOfSourceFilesWritten = 0;
 #ifdef _WIN32
   this->UseLinkScript = false;
 #else
@@ -118,87 +116,39 @@ cmGlobalUnixMakefileGenerator3
   this->MultipleOutputPairs.insert(p);
 }
 
-//----------------------------------------------------------------------------
-int cmGlobalUnixMakefileGenerator3::ShouldAddProgressRule() 
-{
-  // add progress to 100 source files
-  if (this->NumberOfSourceFiles && 
-      (((this->NumberOfSourceFilesWritten + 1)*100)/this->NumberOfSourceFiles)
-      -(this->NumberOfSourceFilesWritten*100)/this->NumberOfSourceFiles)
-    {
-    this->NumberOfSourceFilesWritten++;    
-    return (this->NumberOfSourceFilesWritten*100)/this->NumberOfSourceFiles;
-    }
-  this->NumberOfSourceFilesWritten++;
-  return 0;
-}
-
-int cmGlobalUnixMakefileGenerator3::
-GetNumberOfCompilableSourceFilesForTarget(cmTarget &tgt)
-{
-  std::map<cmStdString, int >::iterator tgtI = 
-    this->TargetSourceFileCount.find(tgt.GetName());
-  if (tgtI != this->TargetSourceFileCount.end())
-    {
-    return tgtI->second;
-    }
-  
-  int result = 0;
-  
-  if((tgt.GetType() == cmTarget::EXECUTABLE) ||
-     (tgt.GetType() == cmTarget::STATIC_LIBRARY) ||
-     (tgt.GetType() == cmTarget::SHARED_LIBRARY) ||
-     (tgt.GetType() == cmTarget::MODULE_LIBRARY) )
-    {
-    std::vector<cmSourceFile*>& sources = tgt.GetSourceFiles();
-    for(std::vector<cmSourceFile*>::iterator source = sources.begin();
-        source != sources.end(); ++source)
-      {
-      if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY") &&
-         !(*source)->GetCustomCommand())
-        {
-        if(!this->IgnoreFile((*source)->GetSourceExtension().c_str()))
-          {
-          const char* lang = 
-            static_cast<cmLocalUnixMakefileGenerator3 *>
-            (tgt.GetMakefile()->GetLocalGenerator())
-            ->GetSourceFileLanguage(**source);
-          if(lang)
-            {
-            result++;
-            }
-          }
-        }
-      }
-    }
-  this->TargetSourceFileCount[tgt.GetName()] = result;
-  return result;
-}
-
 
 //----------------------------------------------------------------------------
 void cmGlobalUnixMakefileGenerator3::Generate() 
 {
+  // first do superclass method
+  this->cmGlobalGenerator::Generate();
+
   // initialize progress
-  this->NumberOfSourceFiles = 0;
   unsigned int i;
+  unsigned long total = 0;
   for (i = 0; i < this->LocalGenerators.size(); ++i)
     {
-    // for all of out targets
-    for (cmTargets::iterator l = 
-           this->LocalGenerators[i]->GetMakefile()->GetTargets().begin();
-         l != this->LocalGenerators[i]->GetMakefile()->GetTargets().end(); 
-         l++)
-      {
-      this->NumberOfSourceFiles += 
-        this->GetNumberOfCompilableSourceFilesForTarget(l->second);
-      }
+    cmLocalUnixMakefileGenerator3 *lg = 
+      static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
+    total += lg->GetNumberOfProgressActions();
     }
-  this->NumberOfSourceFilesWritten = 0;
-
-  // first do superclass method
-  this->cmGlobalGenerator::Generate();
 
+  // write each target's progress.make
+  unsigned long current = 0;
+  for (i = 1; i < this->LocalGenerators.size(); ++i)
+    {
+    cmLocalUnixMakefileGenerator3 *lg = 
+      static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
+    lg->WriteProgressVariables(total,current);
+    }
+  // write the top one last to get the total count
+  if (this->LocalGenerators.size())
+    {
+    cmLocalUnixMakefileGenerator3 *lg = 
+      static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[0]);
+    lg->WriteProgressVariables(total,current);
+    }
+  
   // write the main makefile
   this->WriteMainMakefile2();
   this->WriteMainCMakefile();
@@ -869,7 +819,7 @@ cmGlobalUnixMakefileGenerator3
                                cmLocalGenerator::SHELL);
         //
         progCmd << " " 
-                << this->GetTargetTotalNumberOfProgressFiles(t->second);
+                << this->GetTargetTotalNumberOfActions(t->second);
         commands.push_back(progCmd.str());
         }
         std::string tmp = cmake::GetCMakeFilesDirectoryPostSlash();
@@ -940,7 +890,7 @@ cmGlobalUnixMakefileGenerator3
 
 //----------------------------------------------------------------------------
 int cmGlobalUnixMakefileGenerator3
-::GetTargetTotalNumberOfProgressFiles(cmTarget& target)
+::GetTargetTotalNumberOfActions(cmTarget& target)
 {
   cmLocalUnixMakefileGenerator3 *lg = 
     static_cast<cmLocalUnixMakefileGenerator3 *>
@@ -951,12 +901,54 @@ int cmGlobalUnixMakefileGenerator3
   std::vector<cmTarget *>::iterator i;
   for (i = depends.begin(); i != depends.end(); ++i)
     {
-    result += this->GetTargetTotalNumberOfProgressFiles(**i);
+    result += this->GetTargetTotalNumberOfActions(**i);
     }
   
   return result;
 }
 
+unsigned long cmGlobalUnixMakefileGenerator3::
+GetNumberOfProgressActionsInAll(cmLocalUnixMakefileGenerator3 *lg)
+{
+  unsigned long result = 0;
+
+  // for every target in the top level all
+  if (!lg->GetParent())
+    {
+    // loop over the generators and targets
+    unsigned int i;
+    cmLocalUnixMakefileGenerator3 *lg3;
+    for (i = 0; i < this->LocalGenerators.size(); ++i)
+      {
+      lg3 = static_cast<cmLocalUnixMakefileGenerator3 *>
+        (this->LocalGenerators[i]);
+      // for each target Generate the rule files for each target.
+      cmTargets& targets = lg3->GetMakefile()->GetTargets();
+      for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
+        {
+        if((t->second.GetType() == cmTarget::EXECUTABLE) ||
+           (t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
+           (t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
+           (t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
+           (t->second.GetType() == cmTarget::UTILITY))
+          {
+          if (t->second.IsInAll())
+            {
+            std::vector<int> &progFiles = lg3->ProgressFiles[t->first];
+            result += progFiles.size();
+            }
+          }
+        }
+      }
+    }
+  else
+    {
+    // TODO: would be nice to report progress for subdir "all" targets
+    return 0;
+    }
+  return result;
+}
+
 
 //----------------------------------------------------------------------------
 std::vector<cmTarget *>& cmGlobalUnixMakefileGenerator3

+ 4 - 8
Source/cmGlobalUnixMakefileGenerator3.h

@@ -123,11 +123,10 @@ public:
    const char *targetName,
    const char* config, bool ignoreErrors, bool fast);
 
-  // returns true if a progress rule should be added
-  int ShouldAddProgressRule();
-  int GetNumberOfCompilableSourceFilesForTarget(cmTarget &tgt);
-  int GetTargetTotalNumberOfProgressFiles(cmTarget& target);
-  int GetNumberOfSourceFiles() { return this->NumberOfSourceFiles; };
+  // returns some progress informaiton
+  int GetTargetTotalNumberOfActions(cmTarget& target);
+  unsigned long GetNumberOfProgressActionsInAll
+  (cmLocalUnixMakefileGenerator3 *lg);
 
   // what targets does the specified target depend on
   std::vector<cmTarget *>& GetTargetDepends(cmTarget& target);
@@ -183,9 +182,6 @@ protected:
   typedef std::map<cmStdString, cmStdString> MultipleOutputPairsType;
   MultipleOutputPairsType MultipleOutputPairs;
 
-  int NumberOfSourceFiles;
-  int NumberOfSourceFilesWritten;
-
   std::map<cmStdString, std::vector<cmTarget *> > TargetDependencies;
   std::map<cmStdString, int > TargetSourceFileCount;
 };

+ 66 - 15
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -100,17 +100,72 @@ void cmLocalUnixMakefileGenerator3::Generate()
   
   // Write the cmake file with information for this directory.
   this->WriteDirectoryInformationFile();
-  
+}
+
+//----------------------------------------------------------------------------
+// return info about progress actions
+unsigned long cmLocalUnixMakefileGenerator3::GetNumberOfProgressActions()
+{
+  unsigned long result = 0;
+
+  for (std::vector<cmMakefileTargetGenerator *>::iterator mtgIter = 
+         this->TargetGenerators.begin();
+       mtgIter != this->TargetGenerators.end(); ++mtgIter)
+    {
+    result += (*mtgIter)->GetNumberOfProgressActions();
+    }  
+  return result;
+}
+
+//----------------------------------------------------------------------------
+// return info about progress actions
+unsigned long cmLocalUnixMakefileGenerator3
+::GetNumberOfProgressActionsForTarget(const char *name)
+{
+  for (std::vector<cmMakefileTargetGenerator *>::iterator mtgIter = 
+         this->TargetGenerators.begin();
+       mtgIter != this->TargetGenerators.end(); ++mtgIter)
+    {
+    if (!strcmp(name,(*mtgIter)->GetTargetName()))
+      {
+      return (*mtgIter)->GetNumberOfProgressActions();
+      }
+    }  
+  return 0;
+}
+
+
+//----------------------------------------------------------------------------
+// writes the progreess variables and also closes out the targets
+void cmLocalUnixMakefileGenerator3
+::WriteProgressVariables(unsigned long total,
+                         unsigned long &current)
+{
   // delete the makefile target generator objects
   for (std::vector<cmMakefileTargetGenerator *>::iterator mtgIter = 
          this->TargetGenerators.begin();
        mtgIter != this->TargetGenerators.end(); ++mtgIter)
     {
+    (*mtgIter)->WriteProgressVariables(total,current);
     delete *mtgIter;
     }  
   this->TargetGenerators.clear();
-}
 
+  // write the top level progress for the all target
+  std::string progressFileNameFull = 
+    this->ConvertToFullPath("progress.make");
+  cmGeneratedFileStream ruleFileStream(progressFileNameFull.c_str());
+  if(!ruleFileStream)
+    {
+    return;
+    }
+
+  cmGlobalUnixMakefileGenerator3 *gg = 
+    static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+
+  ruleFileStream << "CMAKE_ALL_PROGRESS = " 
+                 << gg->GetNumberOfProgressActionsInAll(this);
+}
 
 //----------------------------------------------------------------------------
 void cmLocalUnixMakefileGenerator3::ConfigureOutputPaths()
@@ -192,6 +247,12 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
     ruleFileStream.SetCopyIfDifferent(true);
     }
   
+  // Include the progress variables for the target.
+  ruleFileStream
+    << "# Include the progress variables for this target.\n"
+    << this->IncludeDirective << " "
+    << "progress.make\n\n";
+  
   // write the all rules
   this->WriteLocalAllRules(ruleFileStream);
   
@@ -1450,22 +1511,12 @@ void cmLocalUnixMakefileGenerator3
   progressDir += cmake::GetCMakeFilesDirectory();
     {
     cmOStringStream progCmd;
-    progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # src files
+    progCmd << 
+      "$(CMAKE_COMMAND) -E cmake_progress_start ";
     progCmd << this->Convert(progressDir.c_str(),
                              cmLocalGenerator::FULL,
                              cmLocalGenerator::SHELL);
-    cmGlobalUnixMakefileGenerator3 *gg = 
-      static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
-    int n = gg->GetNumberOfSourceFiles();
-    if(n > 100)
-      {
-      n = 100;
-      }
-    if (this->Parent)
-      {
-      n = 0;
-      }
-    progCmd << " " << n;
+    progCmd << " $(CMAKE_ALL_PROGRESS)\n";
     commands.push_back(progCmd.str());
     }
   std::string mf2Dir = cmake::GetCMakeFilesDirectoryPostSlash();

+ 7 - 0
Source/cmLocalUnixMakefileGenerator3.h

@@ -78,6 +78,9 @@ public:
   // write the main variables used by the makefiles
   void WriteMakeVariables(std::ostream& makefileStream);
 
+  // write the progress variables used by the makefiles
+  void WriteProgressVariables(unsigned long total, unsigned long &current);
+
   /**
    * If true, then explicitly pass MAKEFLAGS on the make all target for makes
    * that do not use environment variables.
@@ -208,6 +211,10 @@ public:
   std::map<cmStdString,std::vector<cmTarget *> > GetLocalObjectFiles()
     { return this->LocalObjectFiles;}
 
+  // return info about progress actions
+  unsigned long GetNumberOfProgressActions();
+  unsigned long GetNumberOfProgressActionsForTarget(const char *);
+
 protected:
   // these two methods just compute reasonable values for LibraryOutputPath
   // and ExecutableOutputPath

+ 62 - 10
Source/cmMakefileTargetGenerator.cxx

@@ -33,6 +33,7 @@
 cmMakefileTargetGenerator::cmMakefileTargetGenerator()
 {
   this->BuildFileStream = 0;
+  this->ProgressFileStream = 0;
   this->InfoFileStream = 0;
   this->FlagFileStream = 0;
 }
@@ -85,6 +86,22 @@ void cmMakefileTargetGenerator::CreateRuleFile()
   this->BuildFileNameFull = this->TargetBuildDirectoryFull;
   this->BuildFileNameFull += "/build.make";
 
+  // Construct the rule file name.
+  this->ProgressFileName = this->TargetBuildDirectory;
+  this->ProgressFileName += "/progress.make";
+  this->ProgressFileNameFull = this->TargetBuildDirectoryFull;
+  this->ProgressFileNameFull += "/progress.make";
+
+  this->ProgressFileStream = 
+    new cmGeneratedFileStream(this->ProgressFileNameFull.c_str());
+  if(!this->ProgressFileStream)
+    {
+    return;
+    }
+
+  // reset the progress count
+  this->NumberOfProgressActions = 0;
+
   // Open the rule file.  This should be copy-if-different because the
   // rules may depend on this file itself.
   this->BuildFileStream =
@@ -174,8 +191,17 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
     << "# Include any dependencies generated for this target.\n"
     << this->LocalGenerator->IncludeDirective << " "
     << this->Convert(dependFileNameFull.c_str(),
-                                     cmLocalGenerator::HOME_OUTPUT,
-                                     cmLocalGenerator::MAKEFILE)
+                     cmLocalGenerator::HOME_OUTPUT,
+                     cmLocalGenerator::MAKEFILE)
+    << "\n\n";
+  
+  // Include the progress variables for the target.
+  *this->BuildFileStream
+    << "# Include the progress variables for this target.\n"
+    << this->LocalGenerator->IncludeDirective << " "
+    << this->Convert(this->ProgressFileNameFull.c_str(),
+                     cmLocalGenerator::HOME_OUTPUT,
+                     cmLocalGenerator::MAKEFILE)
     << "\n\n";
 
   // make sure the depend file exists
@@ -410,8 +436,6 @@ cmMakefileTargetGenerator
   // add in a progress call if needed
   cmGlobalUnixMakefileGenerator3* gg =
     static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
-  int prog = gg->ShouldAddProgressRule();
-
   std::string progressDir = this->Makefile->GetHomeOutputDirectory();
   progressDir += cmake::GetCMakeFilesDirectory();
   cmOStringStream progCmd;
@@ -419,12 +443,10 @@ cmMakefileTargetGenerator
   progCmd << this->LocalGenerator->Convert(progressDir.c_str(),
                                            cmLocalGenerator::FULL,
                                            cmLocalGenerator::SHELL);
-  if (prog)
-    {
-    progCmd << " " << prog;
-    this->LocalGenerator->ProgressFiles[this->Target->GetName()].
-      push_back(prog);
-    }
+  this->NumberOfProgressActions++;
+  progCmd << " $(CMAKE_PROGRESS_" 
+          << this->NumberOfProgressActions 
+          << ")";
   commands.push_back(progCmd.str());
 
   std::string buildEcho = "Building ";
@@ -1031,3 +1053,33 @@ void cmMakefileTargetGenerator::RemoveForbiddenFlags(const char* flagVar,
     cmSystemTools::ReplaceString(linkFlags, i->c_str(), "");
     }
 }
+
+void cmMakefileTargetGenerator::WriteProgressVariables(unsigned long total,
+                                                       unsigned long &current)
+{
+  unsigned long num;
+  unsigned long i;
+  for (i = 1; i <= this->NumberOfProgressActions; ++i)
+    {
+    *this->ProgressFileStream
+      << "CMAKE_PROGRESS_" << i << " = ";
+    if (total <= 100)
+      {
+      num = i + current;
+      *this->ProgressFileStream << num;
+      this->LocalGenerator->ProgressFiles[this->Target->GetName()]
+        .push_back(num);
+      }
+    else if (((i+current)*100)/total > ((i-1+current)*100)/total)
+      {
+      num = ((i+current)*100)/total;
+      *this->ProgressFileStream << num;
+      this->LocalGenerator->ProgressFiles[this->Target->GetName()]
+        .push_back(num);
+      }
+    *this->ProgressFileStream << "\n";
+    }
+  current += this->NumberOfProgressActions;
+  delete this->ProgressFileStream;
+}
+

+ 18 - 0
Source/cmMakefileTargetGenerator.h

@@ -50,6 +50,17 @@ public:
      with this target */
   virtual void WriteRuleFiles() = 0;
 
+  /* the main entry point for this class. Writes the Makefiles associated
+     with this target */
+  virtual void WriteProgressVariables(unsigned long total, 
+                                      unsigned long &current);
+  
+  /* return the number of actions that have progress reporting on them */
+  virtual unsigned long GetNumberOfProgressActions() {
+    return this->NumberOfProgressActions;}
+
+  const char *GetTargetName() { return this->TargetName.c_str(); }
+
 protected:
 
   // create the file and directory etc
@@ -115,6 +126,13 @@ protected:
   std::string BuildFileName;
   std::string BuildFileNameFull;
 
+  // the full path to the progress file
+  std::string ProgressFileName;
+  std::string ProgressFileNameFull;
+  // the stream for the build file
+  cmGeneratedFileStream *ProgressFileStream;
+  unsigned long NumberOfProgressActions;
+
   // the path to the directory the build file is in
   std::string TargetBuildDirectory;
   std::string TargetBuildDirectoryFull;