summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBill Hoffman <bill.hoffman@kitware.com>2005-12-09 18:58:55 (GMT)
committerBill Hoffman <bill.hoffman@kitware.com>2005-12-09 18:58:55 (GMT)
commit92b6c8e742df5112afd8b9cf4d0c752fe02a0619 (patch)
treeb1aeef55649f9a93cb0342447225b43ccd842434 /Source
parent3a3ffea532513f823d17276bace8bbe00c8eb50f (diff)
downloadCMake-92b6c8e742df5112afd8b9cf4d0c752fe02a0619.zip
CMake-92b6c8e742df5112afd8b9cf4d0c752fe02a0619.tar.gz
CMake-92b6c8e742df5112afd8b9cf4d0c752fe02a0619.tar.bz2
PERF: apply patch for bug 2575 speeds up depend scanning
Diffstat (limited to 'Source')
-rw-r--r--Source/cmDependsC.cxx175
-rw-r--r--Source/cmDependsC.h18
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx6
3 files changed, 174 insertions, 25 deletions
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index 905b964..5977d28 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -17,6 +17,7 @@
#include "cmDependsC.h"
#include "cmSystemTools.h"
+#include "cmFileTimeComparison.h"
#include <ctype.h> // isspace
@@ -30,18 +31,28 @@ cmDependsC::cmDependsC():
// yummy look at all those constructor arguments
cmDependsC::cmDependsC(std::vector<std::string> const& includes,
const char* scanRegex, const char* complainRegex,
- std::set<cmStdString> const& generatedFiles):
+ std::set<cmStdString> const& generatedFiles,
+ const cmStdString& cacheFileName):
m_IncludePath(&includes),
m_IncludeRegexLine("^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)([\">])"),
m_IncludeRegexScan(scanRegex),
m_IncludeRegexComplain(complainRegex),
- m_GeneratedFiles(&generatedFiles)
+ m_GeneratedFiles(&generatedFiles),
+ m_cacheFileName(cacheFileName)
{
+ this->ReadCacheFile();
}
//----------------------------------------------------------------------------
cmDependsC::~cmDependsC()
{
+ this->WriteCacheFile();
+
+ for (std::map<cmStdString, cmIncludeLines*>::iterator it=m_fileCache.begin();
+ it!=m_fileCache.end(); ++it)
+ {
+ delete it->second;
+ }
}
//----------------------------------------------------------------------------
@@ -142,42 +153,159 @@ bool cmDependsC::WriteDependencies(const char *src, const char *obj,
// Record scanned files.
scanned.insert(fullName);
- // Try to scan the file. Just leave it out if we cannot find
- // it.
- std::ifstream fin(fullName.c_str());
- if(fin)
+ // Check whether this file is already in the cache
+ std::map<cmStdString, cmIncludeLines*>::iterator fileIt=m_fileCache.find(fullName);
+ if (fileIt!=m_fileCache.end())
{
- // Add this file as a dependency.
+ fileIt->second->used=true;
dependencies.insert(fullName);
-
- // Scan this file for new dependencies. Pass the directory
- // containing the file to handle double-quote includes.
- std::string dir = cmSystemTools::GetFilenamePath(fullName);
- this->Scan(fin, dir.c_str());
+ for (std::list<UnscannedEntry>::const_iterator incIt=
+ fileIt->second->list.begin(); incIt!=fileIt->second->list.end(); ++incIt)
+ {
+ if (m_Encountered.find(incIt->FileName) == m_Encountered.end())
+ {
+ m_Encountered.insert(incIt->FileName);
+ m_Unscanned.push(*incIt);
+ }
+ }
+ }
+ else
+ {
+
+ // Try to scan the file. Just leave it out if we cannot find
+ // it.
+ std::ifstream fin(fullName.c_str());
+ if(fin)
+ {
+ // Add this file as a dependency.
+ dependencies.insert(fullName);
+
+ // Scan this file for new dependencies. Pass the directory
+ // containing the file to handle double-quote includes.
+ std::string dir = cmSystemTools::GetFilenamePath(fullName);
+ this->Scan(fin, dir.c_str(), fullName);
+ }
}
}
-
+
first = false;
}
-
+
// Write the dependencies to the output stream.
internalDepends << obj << std::endl;
for(std::set<cmStdString>::iterator i=dependencies.begin();
i != dependencies.end(); ++i)
{
makeDepends << obj << ": "
- << cmSystemTools::ConvertToOutputPath(i->c_str()).c_str()
- << std::endl;
+ << cmSystemTools::ConvertToOutputPath(i->c_str()).c_str()
+ << std::endl;
internalDepends << " " << i->c_str() << std::endl;
}
makeDepends << std::endl;
-
+
return true;
}
//----------------------------------------------------------------------------
-void cmDependsC::Scan(std::istream& is, const char* directory)
+void cmDependsC::ReadCacheFile()
{
+ if(m_cacheFileName.size() == 0)
+ {
+ return;
+ }
+ std::ifstream fin(m_cacheFileName.c_str());
+ if(!fin)
+ {
+ return;
+ }
+
+ std::string line;
+ cmIncludeLines* cacheEntry=0;
+ bool haveFileName=false;
+
+ while(cmSystemTools::GetLineFromStream(fin, line))
+ {
+ if (line.empty())
+ {
+ cacheEntry=0;
+ haveFileName=false;
+ continue;
+ }
+ //the first line after an empty line is the name of the parsed file
+ if (haveFileName==false)
+ {
+ haveFileName=true;
+ int newer=0;
+ cmFileTimeComparison comp;
+ bool res=comp.FileTimeCompare(m_cacheFileName.c_str(), line.c_str(), &newer);
+
+ if ((res==true) && (newer==1)) //cache is newer than the parsed file
+ {
+ cacheEntry=new cmIncludeLines;
+ m_fileCache[line]=cacheEntry;
+ }
+ }
+ else if (cacheEntry!=0)
+ {
+ UnscannedEntry entry;
+ entry.FileName = line;
+ if (cmSystemTools::GetLineFromStream(fin, line))
+ {
+ if (line!="-")
+ {
+ entry.QuotedLocation=line;
+ }
+ cacheEntry->list.push_back(entry);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDependsC::WriteCacheFile() const
+{
+ if(m_cacheFileName.size() == 0)
+ {
+ return;
+ }
+ std::ofstream cacheOut(m_cacheFileName.c_str());
+ if(!cacheOut)
+ {
+ return;
+ }
+
+ for (std::map<cmStdString, cmIncludeLines*>::const_iterator fileIt=m_fileCache.begin();
+ fileIt!=m_fileCache.end(); ++fileIt)
+ {
+ if (fileIt->second->used)
+ {
+ cacheOut<<fileIt->first.c_str()<<std::endl;
+
+ for (std::list<UnscannedEntry>::const_iterator incIt=fileIt->second->list.begin();
+ incIt!=fileIt->second->list.end(); ++incIt)
+ {
+ cacheOut<<incIt->FileName.c_str()<<std::endl;
+ if (incIt->QuotedLocation.empty())
+ {
+ cacheOut<<"-"<<std::endl;
+ }
+ else
+ {
+ cacheOut<<incIt->QuotedLocation.c_str()<<std::endl;
+ }
+ }
+ cacheOut<<std::endl;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmDependsC::Scan(std::istream& is, const char* directory, const cmStdString& fullName)
+{
+ cmIncludeLines* newCacheEntry=new cmIncludeLines;
+ newCacheEntry->used=true;
+ m_fileCache[fullName]=newCacheEntry;
+
// Read one line at a time.
std::string line;
while(cmSystemTools::GetLineFromStream(is, line))
@@ -204,11 +332,14 @@ void cmDependsC::Scan(std::istream& is, const char* directory)
// is included by double-quotes and the other by angle brackets.
// This kind of problem will be fixed when a more
// preprocessor-like implementation of this scanner is created.
- if(m_Encountered.find(entry.FileName) == m_Encountered.end() &&
- m_IncludeRegexScan.find(entry.FileName.c_str()))
+ if (m_IncludeRegexScan.find(entry.FileName.c_str()))
{
- m_Encountered.insert(entry.FileName);
- m_Unscanned.push(entry);
+ newCacheEntry->list.push_back(entry);
+ if(m_Encountered.find(entry.FileName) == m_Encountered.end())
+ {
+ m_Encountered.insert(entry.FileName);
+ m_Unscanned.push(entry);
+ }
}
}
}
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
index 04648fd..e9d335f 100644
--- a/Source/cmDependsC.h
+++ b/Source/cmDependsC.h
@@ -32,7 +32,7 @@ public:
cmDependsC();
cmDependsC(std::vector<std::string> const& includes,
const char* scanRegex, const char* complainRegex,
- std::set<cmStdString> const& generatedFiles);
+ std::set<cmStdString> const& generatedFiles, const cmStdString& cachFileName);
/** Virtual destructor to cleanup subclasses properly. */
virtual ~cmDependsC();
@@ -47,7 +47,7 @@ protected:
std::ostream& internalDepends);
// Method to scan a single file.
- void Scan(std::istream& is, const char* directory);
+ void Scan(std::istream& is, const char* directory, const cmStdString& fullName);
// Method to test for the existence of a file.
bool FileExistsOrIsGenerated(const std::string& fname,
@@ -74,10 +74,24 @@ protected:
cmStdString FileName;
cmStdString QuotedLocation;
};
+
+ struct cmIncludeLines
+ {
+ cmIncludeLines():used(false) {}
+ std::list<UnscannedEntry> list;
+ bool used;
+ };
+
std::set<cmStdString> m_Encountered;
std::queue<UnscannedEntry> m_Unscanned;
t_CharBuffer m_Buffer;
+ std::map<cmStdString, cmIncludeLines *> m_fileCache;
+
+ cmStdString m_cacheFileName;
+
+ void WriteCacheFile() const;
+ void ReadCacheFile();
private:
cmDependsC(cmDependsC const&); // Purposely not implemented.
void operator=(cmDependsC const&); // Purposely not implemented.
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index c89c587..d00e6a1 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -2790,11 +2790,15 @@ cmLocalUnixMakefileGenerator3
cmDepends *scanner = 0;
if(lang == "C" || lang == "CXX" || lang == "RC")
{
+ std::string includeCacheFileName = dir;
+ includeCacheFileName += "/includecache.";
+ includeCacheFileName += lang;
+
// TODO: Handle RC (resource files) dependencies correctly.
scanner = new cmDependsC(includes,
includeRegexScan.c_str(),
includeRegexComplain.c_str(),
- generatedFiles);
+ generatedFiles, includeCacheFileName);
}
#ifdef CMAKE_BUILD_WITH_CMAKE
else if(lang == "Fortran")