This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake".
The branch, next has been updated via 1bc5bbf165a5d818d9589d5b6599727af47afaa3 (commit) via c6f8df7c86b99f41f30ea8c5968f8394d05082cf (commit) via e9316ead07a15e4eb85a8dd92e1e7d42ae5b6ccf (commit) via 69d4ddd992b62c68fe4f6d609a439356d282654d (commit) via 3df749af55c04d5b7bb0ee848c6df112178327bc (commit) via 3029c27e46a193c6319a3c909f938e6614c2b14f (commit) from c8286a5ff5e2c7843a0ee33376dd3b0032317d48 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1bc5bbf165a5d818d9589d5b6599727af47afaa3 commit 1bc5bbf165a5d818d9589d5b6599727af47afaa3 Merge: c8286a5 c6f8df7 Author: Stephen Kelly <steve...@gmail.com> AuthorDate: Tue Oct 20 18:26:56 2015 -0400 Commit: CMake Topic Stage <kwro...@kitware.com> CommitDate: Tue Oct 20 18:26:56 2015 -0400 Merge topic 'inline-cmMakeDepend-content' into next c6f8df7c cmMakeDepend: Inline into inheriting class. e9316ead cmMakeDepend: Inline into only user. 69d4ddd9 cmMakeDepend: Inline into header. 3df749af Remove vestigial declarations. 3029c27e cmMakeDepend: Use public cmMakefile API. https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c6f8df7c86b99f41f30ea8c5968f8394d05082cf commit c6f8df7c86b99f41f30ea8c5968f8394d05082cf Author: Stephen Kelly <steve...@gmail.com> AuthorDate: Mon Oct 19 22:14:14 2015 +0200 Commit: Stephen Kelly <steve...@gmail.com> CommitDate: Wed Oct 21 00:26:04 2015 +0200 cmMakeDepend: Inline into inheriting class. Devirtualize the API. diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index a1500fc..59dafba 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -72,16 +72,13 @@ public: } }; - -// cmMakeDepend is used to generate dependancy information for -// the classes in a makefile -class cmMakeDepend +class cmLBDepend { public: /** * Construct the object with verbose turned off. */ - cmMakeDepend() + cmLBDepend() { this->Verbose = false; this->IncludeFileRegularExpression.compile("^.*$"); @@ -91,7 +88,7 @@ public: /** * Destructor. */ - virtual ~cmMakeDepend() + ~cmLBDepend() { cmDeleteAll(this->DependInformationMap); } @@ -99,7 +96,7 @@ public: /** * Set the makefile that is used as a source of classes. */ - virtual void SetMakefile(cmMakefile* makefile) + void SetMakefile(cmMakefile* makefile) { this->Makefile = makefile; @@ -153,7 +150,7 @@ public: /** * Add a directory to the search path for include files. */ - virtual void AddSearchPath(const std::string& path) + void AddSearchPath(const std::string& path) { this->IncludeDirectories.push_back(path); } @@ -173,25 +170,47 @@ protected: /** * Compute the depend information for this class. */ - virtual void DependWalk(cmDependInformation* info) + + void 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()); + cmSystemTools::Error("error can not open ", info->FullPath.c_str()); return; } - // TODO: Write real read loop (see cmSystemTools::CopyFile). std::string line; - while( cmSystemTools::GetLineFromStream(fin, line) ) + while(cmSystemTools::GetLineFromStream(fin, line)) { - if(includeLine.find(line.c_str())) + 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 = includeLine.match(1); + std::string includeFile = currentline.substr(qstart+1, qend - qstart-1); // see if the include matches the regular expression if(!this->IncludeFileRegularExpression.find(includeFile)) { @@ -205,8 +224,99 @@ protected: } 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<std::string>::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<std::string>::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<std::string>::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<std::string>::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()); + } + } } } } @@ -214,7 +324,7 @@ protected: /** * Add a dependency. Possibly walk it for more dependencies. */ - virtual void AddDependency(cmDependInformation* info, const char* file) + void AddDependency(cmDependInformation* info, const char* file) { cmDependInformation* dependInfo = this->GetDependInformation(file, info->PathOnly.c_str()); @@ -450,164 +560,6 @@ protected: DirectoryToFileToPathMapType DirectoryToFileToPathMap; }; -class cmLBDepend : public cmMakeDepend -{ - /** - * Compute the depend information for this class. - */ - virtual void DependWalk(cmDependInformation* info); -}; - -void cmLBDepend::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<std::string>::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<std::string>::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<std::string>::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<std::string>::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()); - } - } - } - } -} - // cmOutputRequiredFilesCommand bool cmOutputRequiredFilesCommand ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e9316ead07a15e4eb85a8dd92e1e7d42ae5b6ccf commit e9316ead07a15e4eb85a8dd92e1e7d42ae5b6ccf Author: Stephen Kelly <steve...@gmail.com> AuthorDate: Wed Oct 21 00:12:31 2015 +0200 Commit: Stephen Kelly <steve...@gmail.com> CommitDate: Wed Oct 21 00:24:12 2015 +0200 cmMakeDepend: Inline into only user. diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 1c0ec39..fd71b0e 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -299,7 +299,6 @@ set(SRCS cmLocalUnixMakefileGenerator3.cxx cmLocale.h ${MACH_SRCS} - cmMakeDepend.h cmMakefile.cxx cmMakefile.h cmMakefileTargetGenerator.cxx diff --git a/Source/cmMakeDepend.h b/Source/cmMakeDepend.h deleted file mode 100644 index 566f7be..0000000 --- a/Source/cmMakeDepend.h +++ /dev/null @@ -1,461 +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 "cmSystemTools.h" -#include "cmGeneratorExpression.h" -#include "cmAlgorithms.h" - -#include <cmsys/RegularExpression.hxx> -#include <cmsys/FStream.hxx> - -/** \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<cmDependInformation*> 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); - } - } -}; - - -// cmMakeDepend is used to generate dependancy information for -// the classes in a makefile -class cmMakeDepend -{ -public: - /** - * Construct the object with verbose turned off. - */ - cmMakeDepend() - { - this->Verbose = false; - this->IncludeFileRegularExpression.compile("^.*$"); - this->ComplainFileRegularExpression.compile("^$"); - } - - /** - * Destructor. - */ - virtual ~cmMakeDepend() - { - cmDeleteAll(this->DependInformationMap); - } - - /** - * Set the makefile that is used as a source of classes. - */ - virtual 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<std::string> uniqueIncludes; - std::vector<std::string> 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<std::string> includes; - cmSystemTools::ExpandListArgument(incDirs, includes); - - for(std::vector<std::string>::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<std::string>::const_iterator - it = orderedAndUniqueIncludes.begin(); - it != orderedAndUniqueIncludes.end(); - ++it) - { - this->AddSearchPath(*it); - } - } - - /** - * Add a directory to the search path for include files. - */ - virtual 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. - */ - virtual void 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()); - } - } - } - - /** - * Add a dependency. Possibly walk it for more dependencies. - */ - virtual 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<std::string>::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<std::string>::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<std::string>::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<std::string> IncludeDirectories; - typedef std::map<std::string, std::string> FileToPathMapType; - typedef std::map<std::string, FileToPathMapType> - DirectoryToFileToPathMapType; - typedef std::map<std::string, cmDependInformation*> - DependInformationMapType; - DependInformationMapType DependInformationMap; - DirectoryToFileToPathMapType DirectoryToFileToPathMap; -}; - -#endif diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index 2d57d3b..a1500fc 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -10,10 +10,446 @@ See the License for more information. ============================================================================*/ #include "cmOutputRequiredFilesCommand.h" -#include "cmMakeDepend.h" #include "cmAlgorithms.h" #include <cmsys/FStream.hxx> +/** \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<cmDependInformation*> 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); + } + } +}; + + +// cmMakeDepend is used to generate dependancy information for +// the classes in a makefile +class cmMakeDepend +{ +public: + /** + * Construct the object with verbose turned off. + */ + cmMakeDepend() + { + this->Verbose = false; + this->IncludeFileRegularExpression.compile("^.*$"); + this->ComplainFileRegularExpression.compile("^$"); + } + + /** + * Destructor. + */ + virtual ~cmMakeDepend() + { + cmDeleteAll(this->DependInformationMap); + } + + /** + * Set the makefile that is used as a source of classes. + */ + virtual 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<std::string> uniqueIncludes; + std::vector<std::string> 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<std::string> includes; + cmSystemTools::ExpandListArgument(incDirs, includes); + + for(std::vector<std::string>::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<std::string>::const_iterator + it = orderedAndUniqueIncludes.begin(); + it != orderedAndUniqueIncludes.end(); + ++it) + { + this->AddSearchPath(*it); + } + } + + /** + * Add a directory to the search path for include files. + */ + virtual 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. + */ + virtual void 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()); + } + } + } + + /** + * Add a dependency. Possibly walk it for more dependencies. + */ + virtual 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<std::string>::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<std::string>::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<std::string>::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<std::string> IncludeDirectories; + typedef std::map<std::string, std::string> FileToPathMapType; + typedef std::map<std::string, FileToPathMapType> + DirectoryToFileToPathMapType; + typedef std::map<std::string, cmDependInformation*> + DependInformationMapType; + DependInformationMapType DependInformationMap; + DirectoryToFileToPathMapType DirectoryToFileToPathMap; +}; + class cmLBDepend : public cmMakeDepend { /** diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h index 6a09673..b5eb932 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 { https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=69d4ddd992b62c68fe4f6d609a439356d282654d commit 69d4ddd992b62c68fe4f6d609a439356d282654d Author: Stephen Kelly <steve...@gmail.com> AuthorDate: Wed Oct 21 00:09:47 2015 +0200 Commit: Stephen Kelly <steve...@gmail.com> CommitDate: Wed Oct 21 00:22:23 2015 +0200 cmMakeDepend: Inline into header. diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index ee690e6..1c0ec39 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -299,7 +299,6 @@ set(SRCS cmLocalUnixMakefileGenerator3.cxx cmLocale.h ${MACH_SRCS} - cmMakeDepend.cxx cmMakeDepend.h cmMakefile.cxx cmMakefile.h diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx deleted file mode 100644 index f4a22ed..0000000 --- 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 <cmsys/RegularExpression.hxx> -#include <cmsys/FStream.hxx> - -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->GetComplainRegularExpression()); - - // Now extract any include paths from the targets - std::set<std::string> uniqueIncludes; - std::vector<std::string> 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<std::string> includes; - cmSystemTools::ExpandListArgument(incDirs, includes); - - for(std::vector<std::string>::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<std::string>::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<std::string>::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<std::string>::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<std::string>::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 index 2c9d515..566f7be 100644 --- a/Source/cmMakeDepend.h +++ b/Source/cmMakeDepend.h @@ -14,8 +14,12 @@ #include "cmMakefile.h" #include "cmSourceFile.h" +#include "cmSystemTools.h" +#include "cmGeneratorExpression.h" +#include "cmAlgorithms.h" #include <cmsys/RegularExpression.hxx> +#include <cmsys/FStream.hxx> /** \class cmDependInformation * \brief Store dependency information for a single source file. @@ -67,7 +71,13 @@ public: /** * This method adds the dependencies of another file to this one. */ - void AddDependencies(cmDependInformation*); + void AddDependencies(cmDependInformation* info) + { + if(this != info) + { + this->DependencySet.insert(info); + } + } }; @@ -79,59 +89,360 @@ public: /** * Construct the object with verbose turned off. */ - cmMakeDepend(); + cmMakeDepend() + { + this->Verbose = false; + this->IncludeFileRegularExpression.compile("^.*$"); + this->ComplainFileRegularExpression.compile("^$"); + } /** * Destructor. */ - virtual ~cmMakeDepend(); + virtual ~cmMakeDepend() + { + cmDeleteAll(this->DependInformationMap); + } /** * Set the makefile that is used as a source of classes. */ - virtual void SetMakefile(cmMakefile* makefile); + virtual 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<std::string> uniqueIncludes; + std::vector<std::string> 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<std::string> includes; + cmSystemTools::ExpandListArgument(incDirs, includes); + + for(std::vector<std::string>::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<std::string>::const_iterator + it = orderedAndUniqueIncludes.begin(); + it != orderedAndUniqueIncludes.end(); + ++it) + { + this->AddSearchPath(*it); + } + } /** * Add a directory to the search path for include files. */ - virtual void AddSearchPath(const std::string&); + virtual 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); + 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. */ - virtual void DependWalk(cmDependInformation* info); + virtual void 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()); + } + } + } /** * Add a dependency. Possibly walk it for more dependencies. */ - virtual void AddDependency(cmDependInformation* info, const char* file); + virtual 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); + 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<std::string>::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<std::string>::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); + 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 *filename, const char *extraPath); + 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<std::string>::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; diff --git a/bootstrap b/bootstrap index 54f7ca6..9541cc8 100755 --- a/bootstrap +++ b/bootstrap @@ -259,7 +259,6 @@ CMAKE_CXX_SOURCES="\ cmPropertyMap \ cmPropertyDefinition \ cmPropertyDefinitionMap \ - cmMakeDepend \ cmMakefile \ cmExportBuildFileGenerator \ cmExportFileGenerator \ https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3df749af55c04d5b7bb0ee848c6df112178327bc commit 3df749af55c04d5b7bb0ee848c6df112178327bc Author: Stephen Kelly <steve...@gmail.com> AuthorDate: Wed Oct 21 00:15:14 2015 +0200 Commit: Stephen Kelly <steve...@gmail.com> CommitDate: Wed Oct 21 00:19:57 2015 +0200 Remove vestigial declarations. diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index beaddde..7e0f248 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/cmMakefile.h b/Source/cmMakefile.h index 4215b72..ce127d8 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<cmFunctionBlocker*> FunctionBlockersType; FunctionBlockersType FunctionBlockers; std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers; diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index fd4527b..e38c50b 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; https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3029c27e46a193c6319a3c909f938e6614c2b14f commit 3029c27e46a193c6319a3c909f938e6614c2b14f Author: Stephen Kelly <steve...@gmail.com> AuthorDate: Wed Oct 21 00:19:09 2015 +0200 Commit: Stephen Kelly <steve...@gmail.com> CommitDate: Wed Oct 21 00:19:45 2015 +0200 cmMakeDepend: Use public cmMakefile API. diff --git a/Source/cmMakeDepend.cxx b/Source/cmMakeDepend.cxx index cbc7e02..f4a22ed 100644 --- a/Source/cmMakeDepend.cxx +++ b/Source/cmMakeDepend.cxx @@ -51,7 +51,7 @@ void cmMakeDepend::SetMakefile(cmMakefile* makefile) this->IncludeFileRegularExpression.compile( this->Makefile->GetIncludeRegularExpression()); this->ComplainFileRegularExpression.compile( - this->Makefile->ComplainFileRegularExpression.c_str()); + this->Makefile->GetComplainRegularExpression()); // Now extract any include paths from the targets std::set<std::string> uniqueIncludes; ----------------------------------------------------------------------- Summary of changes: Source/CMakeLists.txt | 2 - Source/cmLocalUnixMakefileGenerator3.h | 1 - Source/cmMakeDepend.cxx | 361 ------------------- Source/cmMakeDepend.h | 150 -------- Source/cmMakefile.h | 4 - Source/cmMakefileTargetGenerator.h | 1 - Source/cmOutputRequiredFilesCommand.cxx | 596 +++++++++++++++++++++++++------ Source/cmOutputRequiredFilesCommand.h | 3 +- bootstrap | 1 - 9 files changed, 494 insertions(+), 625 deletions(-) delete mode 100644 Source/cmMakeDepend.cxx delete mode 100644 Source/cmMakeDepend.h hooks/post-receive -- CMake _______________________________________________ Cmake-commits mailing list Cmake-commits@cmake.org http://public.kitware.com/mailman/listinfo/cmake-commits