Browse Source

ENH: always compile progress

Ken Martin 19 years ago
parent
commit
50d058a3a1

+ 194 - 5
Source/cmGlobalUnixMakefileGenerator3.cxx

@@ -20,6 +20,8 @@
 #include "cmMakefile.h"
 #include "cmake.h"
 #include "cmGeneratedFileStream.h"
+#include "cmSourceFile.h"
+#include "cmTarget.h"
 
 cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
 {
@@ -27,6 +29,8 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
   this->ForceUnixPaths = true;
   this->FindMakeProgramFile = "CMakeUnixFindMake.cmake";
   this->ToolSupportsColor = true;
+  this->NumberOfSourceFiles = 0;
+  this->NumberOfSourceFilesWritten = 0;
 }
 
 void cmGlobalUnixMakefileGenerator3
@@ -109,9 +113,83 @@ cmGlobalUnixMakefileGenerator3
   this->MultipleOutputPairs.insert(p);
 }
 
+//----------------------------------------------------------------------------
+int cmGlobalUnixMakefileGenerator3::ShouldAddProgressRule() 
+{
+  // add progress to 100 source files
+  if ((((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() 
 {
+  // initialize progress
+  this->NumberOfSourceFiles = 0;
+  unsigned int i;
+  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);
+      }
+    }
+  this->NumberOfSourceFilesWritten = 0;
+
   // first do superclass method
   this->cmGlobalGenerator::Generate();
 
@@ -621,10 +699,16 @@ cmGlobalUnixMakefileGenerator3
           
           // Write the rule.
           commands.clear();
+          cmOStringStream progCmd;
+          progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
+          progCmd << lg->GetMakefile()->GetHomeOutputDirectory();
+          progCmd << "/CMakeFiles ";
+          progCmd << 
+            (100*this->GetTargetTotalNumberOfSourceFiles(t->second))/
+            this->GetNumberOfSourceFiles();
+          commands.push_back(progCmd.str());
           commands.push_back(lg->GetRecursiveMakeCall
                              ("CMakeFiles/Makefile2",t->second.GetName()));
-          std::string echoCommand = "@echo \"\"";
-          commands.push_back(echoCommand.c_str());
           depends.clear(); 
           depends.push_back("cmake_check_build_system");
           lg->WriteMakeRule(ruleFileStream, 
@@ -714,9 +798,7 @@ cmGlobalUnixMakefileGenerator3
           << "# Target rules for target "
           << localName << "\n\n";
       
-        commands.clear();
-        std::string echoCommand = "@$(CMAKE_COMMAND) -E echo_append \".\"";
-        commands.push_back(echoCommand.c_str());
+        commands.clear();        
         if (t->second.GetType() != cmTarget::UTILITY)
           {
           makeTargetName = localName;
@@ -742,6 +824,21 @@ cmGlobalUnixMakefileGenerator3
         localName += "/all";
         depends.clear();
 
+        cmOStringStream progCmd;
+        progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report ";
+        progCmd << lg->GetMakefile()->GetHomeOutputDirectory();
+        progCmd << "/CMakeFiles ";
+        std::vector<int> &progFiles = lg->ProgressFiles[t->first];
+        for (std::vector<int>::iterator i = progFiles.begin();
+             i != progFiles.end(); ++i)
+          {
+          progCmd << " " << *i;
+          }
+        if (progFiles.size())
+          {
+          commands.push_back(progCmd.str());
+          }
+
         this->AppendGlobalTargetDepends(depends,t->second);
         lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
                           localName.c_str(), depends, commands, true);
@@ -814,6 +911,98 @@ cmGlobalUnixMakefileGenerator3
     }
 }
 
+//----------------------------------------------------------------------------
+int cmGlobalUnixMakefileGenerator3
+::GetTargetTotalNumberOfSourceFiles(cmTarget& target)
+{
+  int result = this->GetNumberOfCompilableSourceFilesForTarget(target);
+  std::vector<cmTarget *>& depends = this->GetTargetDepends(target);
+
+  std::vector<cmTarget *>::iterator i;
+  for (i = depends.begin(); i != depends.end(); ++i)
+    {
+    result += this->GetTargetTotalNumberOfSourceFiles(**i);
+    }
+  
+  return result;
+}
+
+
+//----------------------------------------------------------------------------
+std::vector<cmTarget *>& cmGlobalUnixMakefileGenerator3
+::GetTargetDepends(cmTarget& target)
+{
+  // if the depends are already in the map then return
+  std::map<cmStdString, std::vector<cmTarget *> >::iterator tgtI = 
+    this->TargetDependencies.find(target.GetName());
+  if (tgtI != this->TargetDependencies.end())
+    {
+    return tgtI->second;
+    }
+  
+  // A target should not depend on itself.
+  std::set<cmStdString> emitted;
+  emitted.insert(target.GetName());
+  
+  // the vector of results
+  std::vector<cmTarget *>& result = 
+    this->TargetDependencies[target.GetName()];
+  
+  // Loop over all library dependencies but not for static libs
+  if (target.GetType() != cmTarget::STATIC_LIBRARY)
+    {
+    const cmTarget::LinkLibraryVectorType& tlibs = target.GetLinkLibraries();
+    for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin();
+        lib != tlibs.end(); ++lib)
+      {
+      // Don't emit the same library twice for this target.
+      if(emitted.insert(lib->first).second)
+        {
+        cmTarget *target2 = 
+          target.GetMakefile()->FindTarget(lib->first.c_str());
+        
+        // search each local generator until a match is found
+        if (!target2)
+          {
+          target2 = this->FindTarget(0,lib->first.c_str());
+          }
+        
+        // if a match was found then ...
+        if (target2)
+          {
+          // Add this dependency.
+          result.push_back(target2);
+          }
+        }
+      }
+    }
+  
+  // Loop over all utility dependencies.
+  const std::set<cmStdString>& tutils = target.GetUtilities();
+  for(std::set<cmStdString>::const_iterator util = tutils.begin();
+      util != tutils.end(); ++util)
+    {
+    // Don't emit the same utility twice for this target.
+    if(emitted.insert(*util).second)
+      {
+      cmTarget *target2 = target.GetMakefile()->FindTarget(util->c_str());
+      
+      // search each local generator until a match is found
+      if (!target2)
+        {
+        target2 = this->FindTarget(0,util->c_str());
+        }
+      
+      // if a match was found then ...
+      if (target2)
+        {
+        // Add this dependency.
+        result.push_back(target2);
+        }
+      }
+    }
+  return result;
+}
 
 //----------------------------------------------------------------------------
 void

+ 15 - 0
Source/cmGlobalUnixMakefileGenerator3.h

@@ -123,6 +123,15 @@ public:
    const char *targetName,
    const char* config, bool ignoreErrors);
 
+  // returns true if a progress rule should be added
+  int ShouldAddProgressRule();
+  int GetNumberOfSourceFiles() {return this->NumberOfSourceFiles; }
+  int GetNumberOfCompilableSourceFilesForTarget(cmTarget &tgt);
+  int GetTargetTotalNumberOfSourceFiles(cmTarget& target);
+  
+  // what targets does the specified target depend on
+  std::vector<cmTarget *>& GetTargetDepends(cmTarget& target);
+
 protected:
   void WriteMainMakefile2();
   void WriteMainCMakefile();
@@ -173,6 +182,12 @@ protected:
 
   typedef std::map<cmStdString, cmStdString> MultipleOutputPairsType;
   MultipleOutputPairsType MultipleOutputPairs;
+
+  size_t NumberOfSourceFiles;
+  size_t NumberOfSourceFilesWritten;
+
+  std::map<cmStdString, std::vector<cmTarget *> > TargetDependencies;
+  std::map<cmStdString, int > TargetSourceFileCount;
 };
 
 #endif

+ 21 - 2
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -1408,13 +1408,32 @@ void cmLocalUnixMakefileGenerator3
 
   depends.push_back("cmake_check_build_system");
 
+  if (!this->Parent)
+    {
+    cmGlobalUnixMakefileGenerator3 *gg = 
+      static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+    cmOStringStream progCmd;
+    progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
+    progCmd << this->Makefile->GetHomeOutputDirectory();
+    progCmd << "/CMakeFiles 100";
+    commands.push_back(progCmd.str());
+    }
+
   commands.push_back
     (this->GetRecursiveMakeCall("CMakeFiles/Makefile2",dir.c_str()));  
   this->CreateCDCommand(commands,
                                 this->Makefile->GetHomeOutputDirectory(),
                                 this->Makefile->GetStartOutputDirectory());
-  std::string echoCommand = "@echo \"\"";
-  commands.push_back(echoCommand.c_str());
+  if (!this->Parent)
+    {
+    cmGlobalUnixMakefileGenerator3 *gg = 
+      static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+    cmOStringStream progCmd;
+    progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
+    progCmd << this->Makefile->GetHomeOutputDirectory();
+    progCmd << "/CMakeFiles 0";
+    commands.push_back(progCmd.str());
+    }
   this->WriteMakeRule(ruleFileStream, "The main all target", "all",
                       depends, commands, true);
 

+ 3 - 0
Source/cmLocalUnixMakefileGenerator3.h

@@ -280,11 +280,14 @@ protected:
                           cmTarget& target, const char* filename =0);
 
   bool ForceVerboseMakefiles;
+  std::map<cmStdString, std::vector<int> > ProgressFiles;
+
 private:
   friend class cmMakefileTargetGenerator;
   friend class cmMakefileExecutableTargetGenerator;
   friend class cmMakefileLibraryTargetGenerator;
   friend class cmMakefileUtilityTargetGenerator;
+  friend class cmGlobalUnixMakefileGenerator3;
   
   std::map<cmStdString, IntegrityCheckSetMap> CheckDependFiles;
 

+ 16 - 5
Source/cmMacroCommand.cxx

@@ -252,11 +252,14 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
 {
   // record commands until we hit the ENDMACRO
   // at the ENDMACRO call we shift gears and start looking for invocations
-  if(cmSystemTools::LowerCase(lff.Name) == "endmacro")
+  if(cmSystemTools::LowerCase(lff.Name) == "macro")
     {
-    std::vector<std::string> expandedArguments;
-    mf.ExpandArguments(lff.Arguments, expandedArguments);
-    if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0]))
+    this->Depth++;
+    }
+  else if(cmSystemTools::LowerCase(lff.Name) == "endmacro")
+    {
+    // if this is the endmacro for this macro then execute
+    if (!this->Depth) 
       {
       std::string name = this->Args[0];
       std::vector<std::string>::size_type cc;
@@ -280,6 +283,11 @@ IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf)
       mf.RemoveFunctionBlocker(lff);
       return true;
       }
+    else
+      {
+      // decrement for each nested macro that ends
+      this->Depth--;
+      }
     }
 
   // if it wasn't an endmacro and we are not executing then we must be
@@ -296,11 +304,14 @@ ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf)
     {
     std::vector<std::string> expandedArguments;
     mf.ExpandArguments(lff.Arguments, expandedArguments);
-    if(!expandedArguments.empty() && (expandedArguments[0] == this->Args[0]))
+    if ((!expandedArguments.empty() && 
+        (expandedArguments[0] == this->Args[0]))
+        || mf.IsOn("CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS"))
       {
       return true;
       }
     }
+
   return false;
 }
 

+ 2 - 1
Source/cmMacroCommand.h

@@ -28,7 +28,7 @@
 class cmMacroFunctionBlocker : public cmFunctionBlocker
 {
 public:
-  cmMacroFunctionBlocker() {}
+  cmMacroFunctionBlocker() {this->Depth=0;}
   virtual ~cmMacroFunctionBlocker() {}
   virtual bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile &mf);
   virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile &mf);
@@ -36,6 +36,7 @@ public:
   
   std::vector<std::string> Args;
   std::vector<cmListFileFunction> Functions;
+  int Depth;
 };
 
 /** \class cmMacroCommand

+ 16 - 0
Source/cmMakefileTargetGenerator.cxx

@@ -381,6 +381,22 @@ cmMakefileTargetGenerator
   this->LocalGenerator->AppendEcho(commands, buildEcho.c_str(),
                                    cmLocalUnixMakefileGenerator3::EchoBuild);
 
+  // add in a progress call if needed
+  cmGlobalUnixMakefileGenerator3* gg =
+    static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+  int prog = gg->ShouldAddProgressRule();
+  if (prog)
+    {
+    cmOStringStream progCmd;
+    progCmd << "$(CMAKE_COMMAND) -E cmake_progress_report ";
+    progCmd << this->Makefile->GetHomeOutputDirectory();
+    progCmd << "/CMakeFiles ";
+    progCmd << prog;
+    commands.push_back(progCmd.str());
+    this->LocalGenerator->ProgressFiles[this->Target->GetName()].
+      push_back(prog);
+    }
+      
   // Construct the compile rules.
   std::string compileRuleVar = "CMAKE_";
   compileRuleVar += lang;

+ 2 - 5
Source/cmake.cxx

@@ -29,9 +29,10 @@
 # include "cmVariableWatch.h"
 # include "cmVersion.h"
 # include <cmsys/Terminal.h>
-# include <cmsys/Directory.hxx>
 #endif
 
+# include <cmsys/Directory.hxx>
+
 // only build kdevelop generator on non-windows platforms
 // when not bootstrapping cmake
 #if !defined(_WIN32)
@@ -977,7 +978,6 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
     // Command to start progress for a build
     else if (args[1] == "cmake_progress_start" && args.size() == 4)
       {
-#if defined(CMAKE_BUILD_WITH_CMAKE)
       // bascially remove the directory
       std::string dirName = args[2];
       dirName += "/Progress";
@@ -993,14 +993,12 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
         fprintf(progFile,"%i\n",count);
         fclose(progFile);
         }
-#endif
       return 0;
       }
 
     // Command to report progress for a build
     else if (args[1] == "cmake_progress_report" && args.size() >= 4)
       {
-#if defined(CMAKE_BUILD_WITH_CMAKE)
       std::string dirName = args[2];
       dirName += "/Progress";
       std::string fName;
@@ -1036,7 +1034,6 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
           }
         fclose(progFile);
         }
-#endif
       return 0;
       }