[Cmake-commits] [cmake-commits] alex committed cmDepends.cxx 1.19 1.20 cmDepends.h 1.15 1.16 cmDependsC.cxx 1.35 1.36 cmDependsC.h 1.22 1.23 cmDependsJava.cxx 1.7 1.8 cmDependsJava.h 1.5 1.6 cmLocalUnixMakefileGenerator3.cxx 1.270 1.271 cmLocalUnixMakefileGenerator3.h 1.90 1.91

cmake-commits at cmake.org cmake-commits at cmake.org
Wed Sep 23 14:02:07 EDT 2009


Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv5184/Source

Modified Files:
	cmDepends.cxx cmDepends.h cmDependsC.cxx cmDependsC.h 
	cmDependsJava.cxx cmDependsJava.h 
	cmLocalUnixMakefileGenerator3.cxx 
	cmLocalUnixMakefileGenerator3.h 
Log Message:
Major optimization of C/C++ dependency scanning.

Now only the dependencies for the file where the dependencies actually may
have changed are rescanned, before that this was done for all source files
even if only one source file had changed.
This reduces e.g. on my machine the time for scanning the dependencies 
of kdelibs/khtml/ when only one file (khtml_global.cpp) has changed from
around 7.5 seconds to 1.2 seconds.

The tests succeed, it does what I expected it to do on kdelibs, and Brad
also reviewed the patch, so I think it should be ok.

Alex


Index: cmLocalUnixMakefileGenerator3.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmLocalUnixMakefileGenerator3.h,v
retrieving revision 1.90
retrieving revision 1.91
diff -C 2 -d -r1.90 -r1.91
*** cmLocalUnixMakefileGenerator3.h	16 Sep 2009 22:01:23 -0000	1.90
--- cmLocalUnixMakefileGenerator3.h	23 Sep 2009 18:02:05 -0000	1.91
***************
*** 20,23 ****
--- 20,26 ----
  #include "cmLocalGenerator.h"
  
+ // for cmDepends::DependencyVector
+ #include "cmDepends.h"
+ 
  class cmCustomCommand;
  class cmDependInformation;
***************
*** 344,348 ****
  
    // Helper methods for dependeny updates.
!   bool ScanDependencies(const char* targetDir);
    void CheckMultipleOutputs(bool verbose);
  
--- 347,352 ----
  
    // Helper methods for dependeny updates.
!   bool ScanDependencies(const char* targetDir,
!                 std::map<std::string, cmDepends::DependencyVector>& validDeps);
    void CheckMultipleOutputs(bool verbose);
  

Index: cmDependsJava.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmDependsJava.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -C 2 -d -r1.5 -r1.6
*** cmDependsJava.h	12 Oct 2005 17:52:29 -0000	1.5
--- cmDependsJava.h	23 Sep 2009 18:02:03 -0000	1.6
***************
*** 37,41 ****
    virtual bool WriteDependencies(const char *src, const char *file,
      std::ostream& makeDepends, std::ostream& internalDepends);
!   virtual bool CheckDependencies(std::istream& internalDepends);
  
  private:
--- 37,42 ----
    virtual bool WriteDependencies(const char *src, const char *file,
      std::ostream& makeDepends, std::ostream& internalDepends);
!   virtual bool CheckDependencies(std::istream& internalDepends,
!                   std::map<std::string, DependencyVector >& validDeps);
  
  private:

Index: cmDepends.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmDepends.cxx,v
retrieving revision 1.19
retrieving revision 1.20
diff -C 2 -d -r1.19 -r1.20
*** cmDepends.cxx	19 Sep 2009 17:02:12 -0000	1.19
--- cmDepends.cxx	23 Sep 2009 18:01:55 -0000	1.20
***************
*** 88,92 ****
  
  //----------------------------------------------------------------------------
! bool cmDepends::Check(const char *makeFile, const char *internalFile)
  {
    // Dependency checks must be done in proper working directory.
--- 88,93 ----
  
  //----------------------------------------------------------------------------
! bool cmDepends::Check(const char *makeFile, const char *internalFile,
!                       std::map<std::string, DependencyVector>& validDeps)
  {
    // Dependency checks must be done in proper working directory.
***************
*** 103,107 ****
    bool okay = true;
    std::ifstream fin(internalFile);
!   if(!(fin && this->CheckDependencies(fin)))
      {
      // Clear all dependencies so they will be regenerated.
--- 104,108 ----
    bool okay = true;
    std::ifstream fin(internalFile);
!   if(!(fin && this->CheckDependencies(fin, validDeps)))
      {
      // Clear all dependencies so they will be regenerated.
***************
*** 147,151 ****
  
  //----------------------------------------------------------------------------
! bool cmDepends::CheckDependencies(std::istream& internalDepends)
  {
    // Parse dependencies from the stream.  If any dependee is missing
--- 148,153 ----
  
  //----------------------------------------------------------------------------
! bool cmDepends::CheckDependencies(std::istream& internalDepends,
!                             std::map<std::string, DependencyVector>& validDeps)
  {
    // Parse dependencies from the stream.  If any dependee is missing
***************
*** 154,157 ****
--- 156,161 ----
    bool okay = true;
    bool dependerExists = false;
+   DependencyVector* currentDependencies = 0;
+ 
    while(internalDepends.getline(this->Dependee, this->MaxPath))
      {
***************
*** 175,178 ****
--- 179,185 ----
        // or the time for cmake -E cmake_depends from 0.3 s down to 0.21 s.
        dependerExists = cmSystemTools::FileExists(this->Depender);
+       DependencyVector tmp;
+       validDeps[this->Depender] = tmp;
+       currentDependencies = &validDeps[this->Depender];
        continue;
        }
***************
*** 190,193 ****
--- 197,205 ----
      const char* dependee = this->Dependee+1;
      const char* depender = this->Depender;
+     if (currentDependencies != 0)
+       {
+       currentDependencies->push_back(dependee);
+       }
+ 
      if(!cmSystemTools::FileExists(dependee))
        {
***************
*** 231,234 ****
--- 243,254 ----
        okay = false;
  
+       // Remove the information of this depender from the map, it needs
+       // to be rescanned
+       if (currentDependencies != 0)
+         {
+         validDeps.erase(this->Depender);
+         currentDependencies = 0;
+         }
+ 
        // Remove the depender to be sure it is rebuilt.
        if (dependerExists)

Index: cmLocalUnixMakefileGenerator3.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmLocalUnixMakefileGenerator3.cxx,v
retrieving revision 1.270
retrieving revision 1.271
diff -C 2 -d -r1.270 -r1.271
*** cmLocalUnixMakefileGenerator3.cxx	22 Sep 2009 18:40:23 -0000	1.270
--- cmLocalUnixMakefileGenerator3.cxx	23 Sep 2009 18:02:03 -0000	1.271
***************
*** 17,21 ****
  #include "cmLocalUnixMakefileGenerator3.h"
  
- #include "cmDepends.h"
  #include "cmGeneratedFileStream.h"
  #include "cmGlobalUnixMakefileGenerator3.h"
--- 17,20 ----
***************
*** 1388,1394 ****
        {
        cmOStringStream msg;
!       msg << "Dependee \"" << internalDependFile
            << "\" is newer than depender \""
!           << dirInfoFile << "\"." << std::endl;
        cmSystemTools::Stdout(msg.str().c_str());
        }
--- 1387,1393 ----
        {
        cmOStringStream msg;
!       msg << "Dependee \"" << dirInfoFile
            << "\" is newer than depender \""
!           << internalDependFile << "\"." << std::endl;
        cmSystemTools::Stdout(msg.str().c_str());
        }
***************
*** 1401,1404 ****
--- 1400,1404 ----
    // files but these will not affect the scanning process so they need
    // not be considered.
+   std::map<std::string, cmDepends::DependencyVector> validDependencies;
    bool needRescanDependencies = false;
    if (needRescanDirInfo == false)
***************
*** 1407,1412 ****
      checker.SetVerbose(verbose);
      checker.SetFileComparison(ftc);
      needRescanDependencies = !checker.Check(dependFile.c_str(),
!                                             internalDependFile.c_str());
      }
  
--- 1407,1423 ----
      checker.SetVerbose(verbose);
      checker.SetFileComparison(ftc);
+     // cmDependsC::Check() fills the vector validDependencies() with the
+     // dependencies for those files where they are still valid, i.e. neither
+     // the files themselves nor any files they depend on have changed.
+     // We don't do that if the CMakeDirectoryInformation.cmake file has 
+     // changed, because then potentially all dependencies have changed.
+     // This information is given later on to cmDependsC, which then only
+     // rescans the files where it did not get valid dependencies via this
+     // dependency vector. This means that in the normal case, when only 
+     // few or one file have been edited, then also only this one file is
+     // actually scanned again, instead of all files for this target.
      needRescanDependencies = !checker.Check(dependFile.c_str(),
!                                             internalDependFile.c_str(),
!                                             validDependencies);
      }
  
***************
*** 1427,1431 ****
  #endif
  
!     return this->ScanDependencies(dir.c_str());
      }
    else
--- 1438,1442 ----
  #endif
  
!     return this->ScanDependencies(dir.c_str(), validDependencies);
      }
    else
***************
*** 1439,1443 ****
  bool
  cmLocalUnixMakefileGenerator3
! ::ScanDependencies(const char* targetDir)
  {
    // Read the directory information file.
--- 1450,1455 ----
  bool
  cmLocalUnixMakefileGenerator3
! ::ScanDependencies(const char* targetDir,
!                  std::map<std::string, cmDepends::DependencyVector>& validDeps)
  {
    // Read the directory information file.
***************
*** 1527,1531 ****
        {
        // TODO: Handle RC (resource files) dependencies correctly.
!       scanner = new cmDependsC(this, targetDir, lang.c_str());
        }
  #ifdef CMAKE_BUILD_WITH_CMAKE
--- 1539,1543 ----
        {
        // TODO: Handle RC (resource files) dependencies correctly.
!       scanner = new cmDependsC(this, targetDir, lang.c_str(), &validDeps);
        }
  #ifdef CMAKE_BUILD_WITH_CMAKE

Index: cmDependsC.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmDependsC.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -C 2 -d -r1.22 -r1.23
*** cmDependsC.h	14 May 2008 15:54:32 -0000	1.22
--- cmDependsC.h	23 Sep 2009 18:01:58 -0000	1.23
***************
*** 31,35 ****
        relative path from the build directory to the target file.  */
    cmDependsC();
!   cmDependsC(cmLocalGenerator* lg, const char* targetDir, const char* lang);
  
    /** Virtual destructor to cleanup subclasses properly.  */
--- 31,36 ----
        relative path from the build directory to the target file.  */
    cmDependsC();
!   cmDependsC(cmLocalGenerator* lg, const char* targetDir, const char* lang,
!              const std::map<std::string, DependencyVector>* validDeps);
  
    /** Virtual destructor to cleanup subclasses properly.  */
***************
*** 84,87 ****
--- 85,89 ----
    };
  protected:
+   const std::map<std::string, DependencyVector>* ValidDeps;
    std::set<cmStdString> Encountered;
    std::queue<UnscannedEntry> Unscanned;

Index: cmDependsC.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmDependsC.cxx,v
retrieving revision 1.35
retrieving revision 1.36
diff -C 2 -d -r1.35 -r1.36
*** cmDependsC.cxx	14 May 2008 15:54:32 -0000	1.35
--- cmDependsC.cxx	23 Sep 2009 18:01:56 -0000	1.36
***************
*** 35,44 ****
  //----------------------------------------------------------------------------
  cmDependsC::cmDependsC()
  {
  }
  
  //----------------------------------------------------------------------------
! cmDependsC::cmDependsC(cmLocalGenerator* lg, const char* targetDir,
!                        const char* lang): cmDepends(lg, targetDir)
  {
    cmMakefile* mf = lg->GetMakefile();
--- 35,49 ----
  //----------------------------------------------------------------------------
  cmDependsC::cmDependsC()
+ : ValidDeps(0)
  {
  }
  
  //----------------------------------------------------------------------------
! cmDependsC::cmDependsC(cmLocalGenerator* lg,
!                    const char* targetDir,
!                    const char* lang,
!                    const std::map<std::string, DependencyVector>* validDeps)
! : cmDepends(lg, targetDir)
! , ValidDeps(validDeps)
  {
    cmMakefile* mf = lg->GetMakefile();
***************
*** 114,117 ****
--- 119,148 ----
      }
  
+   if (this->ValidDeps != 0)
+     {
+     std::map<std::string, DependencyVector>::const_iterator tmpIt =
+                                                     this->ValidDeps->find(obj);
+     if (tmpIt!= this->ValidDeps->end())
+       {
+       // Write the dependencies to the output stream.  Makefile rules
+       // written by the original local generator for this directory
+       // convert the dependencies to paths relative to the home output
+       // directory.  We must do the same here.
+       internalDepends << obj << std::endl;
+       for(DependencyVector::const_iterator i=tmpIt->second.begin();
+          i != tmpIt->second.end(); ++i)
+         {
+         makeDepends << obj << ": " <<
+            this->LocalGenerator->Convert(i->c_str(),
+                                          cmLocalGenerator::HOME_OUTPUT,
+                                          cmLocalGenerator::MAKEFILE)
+            << std::endl;
+         internalDepends << " " << i->c_str() << std::endl;
+         }
+       makeDepends << std::endl;
+       return true;
+       }
+     }
+ 
    // Walk the dependency graph starting with the source file.
    bool first = true;

Index: cmDepends.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmDepends.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -C 2 -d -r1.15 -r1.16
*** cmDepends.h	8 May 2008 14:09:14 -0000	1.15
--- cmDepends.h	23 Sep 2009 18:01:56 -0000	1.16
***************
*** 60,69 ****
    /** Write dependencies for the target file.  */
    bool Write(std::ostream &makeDepends, std::ostream &internalDepends);
!   
    /** Check dependencies for the target file.  Returns true if
        dependencies are okay and false if they must be generated.  If
        they must be generated Clear has already been called to wipe out
!       the old dependencies.  */
!   bool Check(const char *makeFile, const char* internalFile);
  
    /** Clear dependencies for the target file so they will be regenerated.  */
--- 60,73 ----
    /** Write dependencies for the target file.  */
    bool Write(std::ostream &makeDepends, std::ostream &internalDepends);
! 
!   class DependencyVector: public std::vector<std::string> {};
! 
    /** Check dependencies for the target file.  Returns true if
        dependencies are okay and false if they must be generated.  If
        they must be generated Clear has already been called to wipe out
!       the old dependencies.
!       Dependencies which are still valid will be stored in validDeps. */
!   bool Check(const char *makeFile, const char* internalFile,
!              std::map<std::string, DependencyVector>& validDeps);
  
    /** Clear dependencies for the target file so they will be regenerated.  */
***************
*** 84,88 ****
    // Return false if dependencies must be regenerated and true
    // otherwise.
!   virtual bool CheckDependencies(std::istream& internalDepends);
  
    // Finalize the dependency information for the target.
--- 88,93 ----
    // Return false if dependencies must be regenerated and true
    // otherwise.
!   virtual bool CheckDependencies(std::istream& internalDepends,
!                            std::map<std::string, DependencyVector>& validDeps);
  
    // Finalize the dependency information for the target.

Index: cmDependsJava.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmDependsJava.cxx,v
retrieving revision 1.7
retrieving revision 1.8
diff -C 2 -d -r1.7 -r1.8
*** cmDependsJava.cxx	12 Oct 2005 17:52:29 -0000	1.7
--- cmDependsJava.cxx	23 Sep 2009 18:02:01 -0000	1.8
***************
*** 44,48 ****
  }
  
! bool cmDependsJava::CheckDependencies(std::istream&)
  {
    return true;
--- 44,49 ----
  }
  
! bool cmDependsJava::CheckDependencies(std::istream&,
!                              std::map<std::string, DependencyVector >&)
  {
    return true;



More information about the Cmake-commits mailing list