diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index ee690e68a..fd71b0e26 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -299,8 +299,6 @@ set(SRCS cmLocalUnixMakefileGenerator3.cxx cmLocale.h ${MACH_SRCS} - cmMakeDepend.cxx - cmMakeDepend.h cmMakefile.cxx cmMakefile.h cmMakefileTargetGenerator.cxx diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index beadddeb9..7e0f24813 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -19,7 +19,6 @@ class cmCustomCommand; class cmCustomCommandGenerator; -class cmDependInformation; class cmDepends; class cmMakefileTargetGenerator; class cmTarget; diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx deleted file mode 100644 index cbc7e0299..000000000 --- a/Source/cmMakeDepend.cxx +++ /dev/null @@ -1,361 +0,0 @@ -/*============================================================================ - CMake - Cross Platform Makefile Generator - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium - - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ -#include "cmMakeDepend.h" -#include "cmSystemTools.h" -#include "cmGeneratorExpression.h" -#include "cmAlgorithms.h" - -#include -#include - -void cmDependInformation::AddDependencies(cmDependInformation* info) -{ - if(this != info) - { - this->DependencySet.insert(info); - } -} - -cmMakeDepend::cmMakeDepend() -{ - this->Verbose = false; - this->IncludeFileRegularExpression.compile("^.*$"); - this->ComplainFileRegularExpression.compile("^$"); -} - - -cmMakeDepend::~cmMakeDepend() -{ - cmDeleteAll(this->DependInformationMap); -} - - -// Set the makefile that depends will be made from. -// The pointer is kept so the cmSourceFile array can -// be updated with the depend information in the cmMakefile. - -void cmMakeDepend::SetMakefile(cmMakefile* makefile) -{ - this->Makefile = makefile; - - // Now extract the include file regular expression from the makefile. - this->IncludeFileRegularExpression.compile( - this->Makefile->GetIncludeRegularExpression()); - this->ComplainFileRegularExpression.compile( - this->Makefile->ComplainFileRegularExpression.c_str()); - - // Now extract any include paths from the targets - std::set uniqueIncludes; - std::vector orderedAndUniqueIncludes; - cmTargets &targets = this->Makefile->GetTargets(); - for (cmTargets::iterator l = targets.begin(); - l != targets.end(); ++l) - { - const char *incDirProp = l->second.GetProperty("INCLUDE_DIRECTORIES"); - if (!incDirProp) - { - continue; - } - - std::string incDirs = cmGeneratorExpression::Preprocess(incDirProp, - cmGeneratorExpression::StripAllGeneratorExpressions); - - std::vector includes; - cmSystemTools::ExpandListArgument(incDirs, includes); - - for(std::vector::const_iterator j = includes.begin(); - j != includes.end(); ++j) - { - std::string path = *j; - this->Makefile->ExpandVariablesInString(path); - if(uniqueIncludes.insert(path).second) - { - orderedAndUniqueIncludes.push_back(path); - } - } - } - - for(std::vector::const_iterator - it = orderedAndUniqueIncludes.begin(); - it != orderedAndUniqueIncludes.end(); - ++it) - { - this->AddSearchPath(*it); - } -} - - -const cmDependInformation* cmMakeDepend::FindDependencies(const char* file) -{ - cmDependInformation* info = this->GetDependInformation(file,0); - this->GenerateDependInformation(info); - return info; -} - -void cmMakeDepend::GenerateDependInformation(cmDependInformation* info) -{ - // If dependencies are already done, stop now. - if(info->DependDone) - { - return; - } - else - { - // Make sure we don't visit the same file more than once. - info->DependDone = true; - } - const char* path = info->FullPath.c_str(); - if(!path) - { - cmSystemTools::Error( - "Attempt to find dependencies for file without path!"); - return; - } - - bool found = false; - - // If the file exists, use it to find dependency information. - if(cmSystemTools::FileExists(path, true)) - { - // Use the real file to find its dependencies. - this->DependWalk(info); - found = true; - } - - - // See if the cmSourceFile for it has any files specified as - // dependency hints. - if(info->SourceFile != 0) - { - - // Get the cmSourceFile corresponding to this. - const cmSourceFile& cFile = *(info->SourceFile); - // See if there are any hints for finding dependencies for the missing - // file. - if(!cFile.GetDepends().empty()) - { - // Dependency hints have been given. Use them to begin the - // recursion. - for(std::vector::const_iterator file = - cFile.GetDepends().begin(); file != cFile.GetDepends().end(); - ++file) - { - this->AddDependency(info, file->c_str()); - } - - // Found dependency information. We are done. - found = true; - } - } - - if(!found) - { - // Try to find the file amongst the sources - cmSourceFile *srcFile = this->Makefile->GetSource - (cmSystemTools::GetFilenameWithoutExtension(path)); - if (srcFile) - { - if (srcFile->GetFullPath() == path) - { - found=true; - } - else - { - //try to guess which include path to use - for(std::vector::iterator t = - this->IncludeDirectories.begin(); - t != this->IncludeDirectories.end(); ++t) - { - std::string incpath = *t; - if (!incpath.empty() && incpath[incpath.size() - 1] != '/') - { - incpath = incpath + "/"; - } - incpath = incpath + path; - if (srcFile->GetFullPath() == incpath) - { - // set the path to the guessed path - info->FullPath = incpath; - found=true; - } - } - } - } - } - - if(!found) - { - // Couldn't find any dependency information. - if(this->ComplainFileRegularExpression.find(info->IncludeName.c_str())) - { - cmSystemTools::Error("error cannot find dependencies for ", path); - } - else - { - // Destroy the name of the file so that it won't be output as a - // dependency. - info->FullPath = ""; - } - } -} - -// This function actually reads the file specified and scans it for -// #include directives -void cmMakeDepend::DependWalk(cmDependInformation* info) -{ - cmsys::RegularExpression includeLine - ("^[ \t]*#[ \t]*include[ \t]*[<\"]([^\">]+)[\">]"); - cmsys::ifstream fin(info->FullPath.c_str()); - if(!fin) - { - cmSystemTools::Error("Cannot open ", info->FullPath.c_str()); - return; - } - - // TODO: Write real read loop (see cmSystemTools::CopyFile). - std::string line; - while( cmSystemTools::GetLineFromStream(fin, line) ) - { - if(includeLine.find(line.c_str())) - { - // extract the file being included - std::string includeFile = includeLine.match(1); - // see if the include matches the regular expression - if(!this->IncludeFileRegularExpression.find(includeFile)) - { - if(this->Verbose) - { - std::string message = "Skipping "; - message += includeFile; - message += " for file "; - message += info->FullPath.c_str(); - cmSystemTools::Error(message.c_str(), 0); - } - continue; - } - - // Add this file and all its dependencies. - this->AddDependency(info, includeFile.c_str()); - } - } -} - - -void cmMakeDepend::AddDependency(cmDependInformation* info, const char* file) -{ - cmDependInformation* dependInfo = - this->GetDependInformation(file, info->PathOnly.c_str()); - this->GenerateDependInformation(dependInfo); - info->AddDependencies(dependInfo); -} - -cmDependInformation* cmMakeDepend::GetDependInformation(const char* file, - const char *extraPath) -{ - // Get the full path for the file so that lookup is unambiguous. - std::string fullPath = this->FullPath(file, extraPath); - - // Try to find the file's instance of cmDependInformation. - DependInformationMapType::const_iterator result = - this->DependInformationMap.find(fullPath); - if(result != this->DependInformationMap.end()) - { - // Found an instance, return it. - return result->second; - } - else - { - // Didn't find an instance. Create a new one and save it. - cmDependInformation* info = new cmDependInformation; - info->FullPath = fullPath; - info->PathOnly = cmSystemTools::GetFilenamePath(fullPath); - info->IncludeName = file; - this->DependInformationMap[fullPath] = info; - return info; - } -} - - -// find the full path to fname by searching the this->IncludeDirectories array -std::string cmMakeDepend::FullPath(const char* fname, const char *extraPath) -{ - DirectoryToFileToPathMapType::iterator m; - if(extraPath) - { - m = this->DirectoryToFileToPathMap.find(extraPath); - } - else - { - m = this->DirectoryToFileToPathMap.find(""); - } - - if(m != this->DirectoryToFileToPathMap.end()) - { - FileToPathMapType& map = m->second; - FileToPathMapType::iterator p = map.find(fname); - if(p != map.end()) - { - return p->second; - } - } - - if(cmSystemTools::FileExists(fname, true)) - { - std::string fp = cmSystemTools::CollapseFullPath(fname); - this->DirectoryToFileToPathMap[extraPath? extraPath: ""][fname] = fp; - return fp; - } - - for(std::vector::iterator i = this->IncludeDirectories.begin(); - i != this->IncludeDirectories.end(); ++i) - { - std::string path = *i; - if (!path.empty() && path[path.size() - 1] != '/') - { - path = path + "/"; - } - path = path + fname; - if(cmSystemTools::FileExists(path.c_str(), true) - && !cmSystemTools::FileIsDirectory(path)) - { - std::string fp = cmSystemTools::CollapseFullPath(path); - this->DirectoryToFileToPathMap[extraPath? extraPath: ""][fname] = fp; - return fp; - } - } - - if (extraPath) - { - std::string path = extraPath; - if (!path.empty() && path[path.size() - 1] != '/') - { - path = path + "/"; - } - path = path + fname; - if(cmSystemTools::FileExists(path.c_str(), true) - && !cmSystemTools::FileIsDirectory(path)) - { - std::string fp = cmSystemTools::CollapseFullPath(path); - this->DirectoryToFileToPathMap[extraPath][fname] = fp; - return fp; - } - } - - // Couldn't find the file. - return std::string(fname); -} - -// Add a directory to the search path -void cmMakeDepend::AddSearchPath(const std::string& path) -{ - this->IncludeDirectories.push_back(path); -} diff --git a/Source/cmMakeDepend.h b/Source/cmMakeDepend.h deleted file mode 100644 index 2c9d51541..000000000 --- a/Source/cmMakeDepend.h +++ /dev/null @@ -1,150 +0,0 @@ -/*============================================================================ - CMake - Cross Platform Makefile Generator - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium - - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ -#ifndef cmMakeDepend_h -#define cmMakeDepend_h - -#include "cmMakefile.h" -#include "cmSourceFile.h" - -#include - -/** \class cmDependInformation - * \brief Store dependency information for a single source file. - * - * This structure stores the depend information for a single source file. - */ -class cmDependInformation -{ -public: - /** - * Construct with dependency generation marked not done; instance - * not placed in cmMakefile's list. - */ - cmDependInformation(): DependDone(false), SourceFile(0) {} - - /** - * The set of files on which this one depends. - */ - typedef std::set DependencySetType; - DependencySetType DependencySet; - - /** - * This flag indicates whether dependency checking has been - * performed for this file. - */ - bool DependDone; - - /** - * If this object corresponds to a cmSourceFile instance, this points - * to it. - */ - const cmSourceFile *SourceFile; - - /** - * Full path to this file. - */ - std::string FullPath; - - /** - * Full path not including file name. - */ - std::string PathOnly; - - /** - * Name used to #include this file. - */ - std::string IncludeName; - - /** - * This method adds the dependencies of another file to this one. - */ - void AddDependencies(cmDependInformation*); -}; - - -// cmMakeDepend is used to generate dependancy information for -// the classes in a makefile -class cmMakeDepend -{ -public: - /** - * Construct the object with verbose turned off. - */ - cmMakeDepend(); - - /** - * Destructor. - */ - virtual ~cmMakeDepend(); - - /** - * Set the makefile that is used as a source of classes. - */ - virtual void SetMakefile(cmMakefile* makefile); - - /** - * Add a directory to the search path for include files. - */ - virtual void AddSearchPath(const std::string&); - - /** - * Generate dependencies for the file given. Returns a pointer to - * the cmDependInformation object for the file. - */ - const cmDependInformation* FindDependencies(const char* file); - -protected: - /** - * Compute the depend information for this class. - */ - virtual void DependWalk(cmDependInformation* info); - - /** - * Add a dependency. Possibly walk it for more dependencies. - */ - virtual void AddDependency(cmDependInformation* info, const char* file); - - /** - * Fill in the given object with dependency information. If the - * information is already complete, nothing is done. - */ - void GenerateDependInformation(cmDependInformation* info); - - /** - * Get an instance of cmDependInformation corresponding to the given file - * name. - */ - cmDependInformation* GetDependInformation(const char* file, - const char *extraPath); - - /** - * Find the full path name for the given file name. - * This uses the include directories. - * TODO: Cache path conversions to reduce FileExists calls. - */ - std::string FullPath(const char *filename, const char *extraPath); - - cmMakefile* Makefile; - bool Verbose; - cmsys::RegularExpression IncludeFileRegularExpression; - cmsys::RegularExpression ComplainFileRegularExpression; - std::vector IncludeDirectories; - typedef std::map FileToPathMapType; - typedef std::map - DirectoryToFileToPathMapType; - typedef std::map - DependInformationMapType; - DependInformationMapType DependInformationMap; - DirectoryToFileToPathMapType DirectoryToFileToPathMap; -}; - -#endif diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 0b8db3cbf..725448b9e 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -41,7 +41,6 @@ class cmFunctionBlocker; class cmCommand; class cmInstallGenerator; -class cmMakeDepend; class cmSourceFile; class cmTest; class cmTestGenerator; @@ -856,9 +855,6 @@ private: bool EnforceUniqueDir(const std::string& srcPath, const std::string& binPath) const; - friend class cmMakeDepend; // make depend needs direct access - // to the Sources array - typedef std::vector FunctionBlockersType; FunctionBlockersType FunctionBlockers; std::vector FunctionBlockerBarriers; diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index fd4527bfa..e38c50b0a 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -18,7 +18,6 @@ #include "cmOSXBundleGenerator.h" class cmCustomCommandGenerator; -class cmDependInformation; class cmDepends; class cmGeneratorTarget; class cmGeneratedFileStream; diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index 2d57d3b55..54208acbe 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -10,167 +10,557 @@ See the License for more information. ============================================================================*/ #include "cmOutputRequiredFilesCommand.h" -#include "cmMakeDepend.h" #include "cmAlgorithms.h" #include -class cmLBDepend : public cmMakeDepend +/** \class cmDependInformation + * \brief Store dependency information for a single source file. + * + * This structure stores the depend information for a single source file. + */ +class cmDependInformation { +public: /** - * Compute the depend information for this class. + * Construct with dependency generation marked not done; instance + * not placed in cmMakefile's list. */ - virtual void DependWalk(cmDependInformation* info); + cmDependInformation(): DependDone(false), SourceFile(0) {} + + /** + * The set of files on which this one depends. + */ + typedef std::set DependencySetType; + DependencySetType DependencySet; + + /** + * This flag indicates whether dependency checking has been + * performed for this file. + */ + bool DependDone; + + /** + * If this object corresponds to a cmSourceFile instance, this points + * to it. + */ + const cmSourceFile *SourceFile; + + /** + * Full path to this file. + */ + std::string FullPath; + + /** + * Full path not including file name. + */ + std::string PathOnly; + + /** + * Name used to #include this file. + */ + std::string IncludeName; + + /** + * This method adds the dependencies of another file to this one. + */ + void AddDependencies(cmDependInformation* info) + { + if(this != info) + { + this->DependencySet.insert(info); + } + } }; -void cmLBDepend::DependWalk(cmDependInformation* info) +class cmLBDepend { - cmsys::ifstream fin(info->FullPath.c_str()); - if(!fin) - { - cmSystemTools::Error("error can not open ", info->FullPath.c_str()); - return; - } +public: + /** + * Construct the object with verbose turned off. + */ + cmLBDepend() + { + this->Verbose = false; + this->IncludeFileRegularExpression.compile("^.*$"); + this->ComplainFileRegularExpression.compile("^$"); + } - std::string line; - while(cmSystemTools::GetLineFromStream(fin, line)) - { - if(cmHasLiteralPrefix(line.c_str(), "#include")) + /** + * Destructor. + */ + ~cmLBDepend() + { + cmDeleteAll(this->DependInformationMap); + } + + /** + * Set the makefile that is used as a source of classes. + */ + void SetMakefile(cmMakefile* makefile) + { + this->Makefile = makefile; + + // Now extract the include file regular expression from the makefile. + this->IncludeFileRegularExpression.compile( + this->Makefile->GetIncludeRegularExpression()); + this->ComplainFileRegularExpression.compile( + this->Makefile->GetComplainRegularExpression()); + + // Now extract any include paths from the targets + std::set uniqueIncludes; + std::vector orderedAndUniqueIncludes; + cmTargets &targets = this->Makefile->GetTargets(); + for (cmTargets::iterator l = targets.begin(); + l != targets.end(); ++l) { - // if it is an include line then create a string class - std::string currentline = line; - size_t qstart = currentline.find('\"', 8); - size_t qend; - // if a quote is not found look for a < - if(qstart == std::string::npos) + const char *incDirProp = l->second.GetProperty("INCLUDE_DIRECTORIES"); + if (!incDirProp) { - qstart = currentline.find('<', 8); - // if a < is not found then move on - if(qstart == std::string::npos) - { - cmSystemTools::Error("unknown include directive ", - currentline.c_str() ); - continue; - } - else - { - qend = currentline.find('>', qstart+1); - } - } - else - { - qend = currentline.find('\"', qstart+1); - } - // extract the file being included - std::string includeFile = currentline.substr(qstart+1, qend - qstart-1); - // see if the include matches the regular expression - if(!this->IncludeFileRegularExpression.find(includeFile)) - { - if(this->Verbose) - { - std::string message = "Skipping "; - message += includeFile; - message += " for file "; - message += info->FullPath.c_str(); - cmSystemTools::Error(message.c_str(), 0); - } continue; } - // Add this file and all its dependencies. - this->AddDependency(info, includeFile.c_str()); - /// add the cxx file if it exists - std::string cxxFile = includeFile; - std::string::size_type pos = cxxFile.rfind('.'); - if(pos != std::string::npos) + std::string incDirs = + cmGeneratorExpression::Preprocess(incDirProp, + cmGeneratorExpression::StripAllGeneratorExpressions); + + std::vector includes; + cmSystemTools::ExpandListArgument(incDirs, includes); + + for(std::vector::const_iterator j = includes.begin(); + j != includes.end(); ++j) { - std::string root = cxxFile.substr(0, pos); - cxxFile = root + ".cxx"; - bool found = false; - // try jumping to .cxx .cpp and .c in order - if(cmSystemTools::FileExists(cxxFile.c_str())) + std::string path = *j; + this->Makefile->ExpandVariablesInString(path); + if(uniqueIncludes.insert(path).second) { - found = true; - } - for(std::vector::iterator i = - this->IncludeDirectories.begin(); - i != this->IncludeDirectories.end(); ++i) - { - std::string path = *i; - path = path + "/"; - path = path + cxxFile; - if(cmSystemTools::FileExists(path.c_str())) - { - found = true; - } - } - if (!found) - { - cxxFile = root + ".cpp"; - if(cmSystemTools::FileExists(cxxFile.c_str())) - { - found = true; - } - for(std::vector::iterator i = - this->IncludeDirectories.begin(); - i != this->IncludeDirectories.end(); ++i) - { - std::string path = *i; - path = path + "/"; - path = path + cxxFile; - if(cmSystemTools::FileExists(path.c_str())) - { - found = true; - } - } - } - if (!found) - { - cxxFile = root + ".c"; - if(cmSystemTools::FileExists(cxxFile.c_str())) - { - found = true; - } - for(std::vector::iterator i = - this->IncludeDirectories.begin(); - i != this->IncludeDirectories.end(); ++i) - { - std::string path = *i; - path = path + "/"; - path = path + cxxFile; - if(cmSystemTools::FileExists(path.c_str())) - { - found = true; - } - } - } - if (!found) - { - cxxFile = root + ".txx"; - if(cmSystemTools::FileExists(cxxFile.c_str())) - { - found = true; - } - for(std::vector::iterator i = - this->IncludeDirectories.begin(); - i != this->IncludeDirectories.end(); ++i) - { - std::string path = *i; - path = path + "/"; - path = path + cxxFile; - if(cmSystemTools::FileExists(path.c_str())) - { - found = true; - } - } - } - if (found) - { - this->AddDependency(info, cxxFile.c_str()); + orderedAndUniqueIncludes.push_back(path); } } } - } -} + + for(std::vector::const_iterator + it = orderedAndUniqueIncludes.begin(); + it != orderedAndUniqueIncludes.end(); + ++it) + { + this->AddSearchPath(*it); + } + } + + /** + * Add a directory to the search path for include files. + */ + void AddSearchPath(const std::string& path) + { + this->IncludeDirectories.push_back(path); + } + + /** + * Generate dependencies for the file given. Returns a pointer to + * the cmDependInformation object for the file. + */ + const cmDependInformation* FindDependencies(const char* file) + { + cmDependInformation* info = this->GetDependInformation(file,0); + this->GenerateDependInformation(info); + return info; + } + +protected: + /** + * Compute the depend information for this class. + */ + + void DependWalk(cmDependInformation* info) + { + cmsys::ifstream fin(info->FullPath.c_str()); + if(!fin) + { + cmSystemTools::Error("error can not open ", info->FullPath.c_str()); + return; + } + + std::string line; + while(cmSystemTools::GetLineFromStream(fin, line)) + { + if(cmHasLiteralPrefix(line.c_str(), "#include")) + { + // if it is an include line then create a string class + std::string currentline = line; + size_t qstart = currentline.find('\"', 8); + size_t qend; + // if a quote is not found look for a < + if(qstart == std::string::npos) + { + qstart = currentline.find('<', 8); + // if a < is not found then move on + if(qstart == std::string::npos) + { + cmSystemTools::Error("unknown include directive ", + currentline.c_str() ); + continue; + } + else + { + qend = currentline.find('>', qstart+1); + } + } + else + { + qend = currentline.find('\"', qstart+1); + } + // extract the file being included + std::string includeFile = + currentline.substr(qstart+1, qend - qstart-1); + // see if the include matches the regular expression + if(!this->IncludeFileRegularExpression.find(includeFile)) + { + if(this->Verbose) + { + std::string message = "Skipping "; + message += includeFile; + message += " for file "; + message += info->FullPath.c_str(); + cmSystemTools::Error(message.c_str(), 0); + } + continue; + } + + // Add this file and all its dependencies. + this->AddDependency(info, includeFile.c_str()); + /// add the cxx file if it exists + std::string cxxFile = includeFile; + std::string::size_type pos = cxxFile.rfind('.'); + if(pos != std::string::npos) + { + std::string root = cxxFile.substr(0, pos); + cxxFile = root + ".cxx"; + bool found = false; + // try jumping to .cxx .cpp and .c in order + if(cmSystemTools::FileExists(cxxFile.c_str())) + { + found = true; + } + for(std::vector::iterator i = + this->IncludeDirectories.begin(); + i != this->IncludeDirectories.end(); ++i) + { + std::string path = *i; + path = path + "/"; + path = path + cxxFile; + if(cmSystemTools::FileExists(path.c_str())) + { + found = true; + } + } + if (!found) + { + cxxFile = root + ".cpp"; + if(cmSystemTools::FileExists(cxxFile.c_str())) + { + found = true; + } + for(std::vector::iterator i = + this->IncludeDirectories.begin(); + i != this->IncludeDirectories.end(); ++i) + { + std::string path = *i; + path = path + "/"; + path = path + cxxFile; + if(cmSystemTools::FileExists(path.c_str())) + { + found = true; + } + } + } + if (!found) + { + cxxFile = root + ".c"; + if(cmSystemTools::FileExists(cxxFile.c_str())) + { + found = true; + } + for(std::vector::iterator i = + this->IncludeDirectories.begin(); + i != this->IncludeDirectories.end(); ++i) + { + std::string path = *i; + path = path + "/"; + path = path + cxxFile; + if(cmSystemTools::FileExists(path.c_str())) + { + found = true; + } + } + } + if (!found) + { + cxxFile = root + ".txx"; + if(cmSystemTools::FileExists(cxxFile.c_str())) + { + found = true; + } + for(std::vector::iterator i = + this->IncludeDirectories.begin(); + i != this->IncludeDirectories.end(); ++i) + { + std::string path = *i; + path = path + "/"; + path = path + cxxFile; + if(cmSystemTools::FileExists(path.c_str())) + { + found = true; + } + } + } + if (found) + { + this->AddDependency(info, cxxFile.c_str()); + } + } + } + } + } + + /** + * Add a dependency. Possibly walk it for more dependencies. + */ + void AddDependency(cmDependInformation* info, const char* file) + { + cmDependInformation* dependInfo = + this->GetDependInformation(file, info->PathOnly.c_str()); + this->GenerateDependInformation(dependInfo); + info->AddDependencies(dependInfo); + } + + /** + * Fill in the given object with dependency information. If the + * information is already complete, nothing is done. + */ + void GenerateDependInformation(cmDependInformation* info) + { + // If dependencies are already done, stop now. + if(info->DependDone) + { + return; + } + else + { + // Make sure we don't visit the same file more than once. + info->DependDone = true; + } + const char* path = info->FullPath.c_str(); + if(!path) + { + cmSystemTools::Error( + "Attempt to find dependencies for file without path!"); + return; + } + + bool found = false; + + // If the file exists, use it to find dependency information. + if(cmSystemTools::FileExists(path, true)) + { + // Use the real file to find its dependencies. + this->DependWalk(info); + found = true; + } + + + // See if the cmSourceFile for it has any files specified as + // dependency hints. + if(info->SourceFile != 0) + { + + // Get the cmSourceFile corresponding to this. + const cmSourceFile& cFile = *(info->SourceFile); + // See if there are any hints for finding dependencies for the missing + // file. + if(!cFile.GetDepends().empty()) + { + // Dependency hints have been given. Use them to begin the + // recursion. + for(std::vector::const_iterator file = + cFile.GetDepends().begin(); file != cFile.GetDepends().end(); + ++file) + { + this->AddDependency(info, file->c_str()); + } + + // Found dependency information. We are done. + found = true; + } + } + + if(!found) + { + // Try to find the file amongst the sources + cmSourceFile *srcFile = this->Makefile->GetSource + (cmSystemTools::GetFilenameWithoutExtension(path)); + if (srcFile) + { + if (srcFile->GetFullPath() == path) + { + found=true; + } + else + { + //try to guess which include path to use + for(std::vector::iterator t = + this->IncludeDirectories.begin(); + t != this->IncludeDirectories.end(); ++t) + { + std::string incpath = *t; + if (!incpath.empty() && incpath[incpath.size() - 1] != '/') + { + incpath = incpath + "/"; + } + incpath = incpath + path; + if (srcFile->GetFullPath() == incpath) + { + // set the path to the guessed path + info->FullPath = incpath; + found=true; + } + } + } + } + } + + if(!found) + { + // Couldn't find any dependency information. + if(this->ComplainFileRegularExpression.find(info->IncludeName.c_str())) + { + cmSystemTools::Error("error cannot find dependencies for ", path); + } + else + { + // Destroy the name of the file so that it won't be output as a + // dependency. + info->FullPath = ""; + } + } + } + + /** + * Get an instance of cmDependInformation corresponding to the given file + * name. + */ + cmDependInformation* GetDependInformation(const char* file, + const char *extraPath) + { + // Get the full path for the file so that lookup is unambiguous. + std::string fullPath = this->FullPath(file, extraPath); + + // Try to find the file's instance of cmDependInformation. + DependInformationMapType::const_iterator result = + this->DependInformationMap.find(fullPath); + if(result != this->DependInformationMap.end()) + { + // Found an instance, return it. + return result->second; + } + else + { + // Didn't find an instance. Create a new one and save it. + cmDependInformation* info = new cmDependInformation; + info->FullPath = fullPath; + info->PathOnly = cmSystemTools::GetFilenamePath(fullPath); + info->IncludeName = file; + this->DependInformationMap[fullPath] = info; + return info; + } + } + + /** + * Find the full path name for the given file name. + * This uses the include directories. + * TODO: Cache path conversions to reduce FileExists calls. + */ + std::string FullPath(const char *fname, const char *extraPath) + { + DirectoryToFileToPathMapType::iterator m; + if(extraPath) + { + m = this->DirectoryToFileToPathMap.find(extraPath); + } + else + { + m = this->DirectoryToFileToPathMap.find(""); + } + + if(m != this->DirectoryToFileToPathMap.end()) + { + FileToPathMapType& map = m->second; + FileToPathMapType::iterator p = map.find(fname); + if(p != map.end()) + { + return p->second; + } + } + + if(cmSystemTools::FileExists(fname, true)) + { + std::string fp = cmSystemTools::CollapseFullPath(fname); + this->DirectoryToFileToPathMap[extraPath? extraPath: ""][fname] = fp; + return fp; + } + + for(std::vector::iterator i = + this->IncludeDirectories.begin(); + i != this->IncludeDirectories.end(); ++i) + { + std::string path = *i; + if (!path.empty() && path[path.size() - 1] != '/') + { + path = path + "/"; + } + path = path + fname; + if(cmSystemTools::FileExists(path.c_str(), true) + && !cmSystemTools::FileIsDirectory(path)) + { + std::string fp = cmSystemTools::CollapseFullPath(path); + this->DirectoryToFileToPathMap[extraPath? extraPath: ""][fname] = fp; + return fp; + } + } + + if (extraPath) + { + std::string path = extraPath; + if (!path.empty() && path[path.size() - 1] != '/') + { + path = path + "/"; + } + path = path + fname; + if(cmSystemTools::FileExists(path.c_str(), true) + && !cmSystemTools::FileIsDirectory(path)) + { + std::string fp = cmSystemTools::CollapseFullPath(path); + this->DirectoryToFileToPathMap[extraPath][fname] = fp; + return fp; + } + } + + // Couldn't find the file. + return std::string(fname); + } + + cmMakefile* Makefile; + bool Verbose; + cmsys::RegularExpression IncludeFileRegularExpression; + cmsys::RegularExpression ComplainFileRegularExpression; + std::vector IncludeDirectories; + typedef std::map FileToPathMapType; + typedef std::map + DirectoryToFileToPathMapType; + typedef std::map + DependInformationMapType; + DependInformationMapType DependInformationMap; + DirectoryToFileToPathMapType DirectoryToFileToPathMap; +}; // cmOutputRequiredFilesCommand bool cmOutputRequiredFilesCommand diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h index 6a0967340..b5eb9329a 100644 --- a/Source/cmOutputRequiredFilesCommand.h +++ b/Source/cmOutputRequiredFilesCommand.h @@ -13,7 +13,8 @@ #define cmOutputRequiredFilesCommand_h #include "cmCommand.h" -#include "cmMakeDepend.h" + +class cmDependInformation; class cmOutputRequiredFilesCommand : public cmCommand { diff --git a/bootstrap b/bootstrap index 54f7ca629..9541cc858 100755 --- a/bootstrap +++ b/bootstrap @@ -259,7 +259,6 @@ CMAKE_CXX_SOURCES="\ cmPropertyMap \ cmPropertyDefinition \ cmPropertyDefinitionMap \ - cmMakeDepend \ cmMakefile \ cmExportBuildFileGenerator \ cmExportFileGenerator \