diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 876ee9fc1..00c6b1f70 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -39,14 +39,15 @@ void cmListFileCache::ClearCache() -cmListFile* cmListFileCache::GetFileCache(const char* path) +cmListFile* cmListFileCache::GetFileCache(const char* path, + bool requireProjectCommand) { ListFileMap::iterator sl = m_ListFileCache.find(path); if (sl == m_ListFileCache.end()) { // if not already in the map, then parse and store the // file - if(!this->CacheFile(path)) + if(!this->CacheFile(path, requireProjectCommand)) { return 0; } @@ -61,7 +62,7 @@ cmListFile* cmListFileCache::GetFileCache(const char* path) cmListFile& ret = sl->second; if(cmSystemTools::ModifiedTime(path) > ret.m_ModifiedTime ) { - if(!this->CacheFile(path)) + if(!this->CacheFile(path, requireProjectCommand)) { return 0; } @@ -75,7 +76,7 @@ cmListFile* cmListFileCache::GetFileCache(const char* path) } -bool cmListFileCache::CacheFile(const char* path) +bool cmListFileCache::CacheFile(const char* path, bool requireProjectCommand) { if(!cmSystemTools::FileExists(path)) { @@ -106,6 +107,30 @@ bool cmListFileCache::CacheFile(const char* path) inFile.m_ModifiedTime = 0; } } + if(requireProjectCommand) + { + bool hasProject = false; + // search for a project command + for(std::vector::iterator i + = inFile.m_Functions.begin(); + i != inFile.m_Functions.end(); ++i) + { + if(i->m_Name == "PROJECT") + { + hasProject = true; + break; + } + } + // if no project command is found, add one + if(!hasProject) + { + cmListFileFunction project; + project.m_Name = "PROJECT"; + project.m_Arguments.push_back("Project"); + inFile.m_Functions.push_back(project); + std::cerr << "adding project command to file " << path << "\n"; + } + } m_ListFileCache[path] = inFile; return true; } diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index 183223408..2520eca1d 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -52,16 +52,18 @@ public: /** Return the cached version of the given file. * If the file is not already in the cache, a cache entry * will be made. If there is an error loading the file, - * NULL is returned. + * NULL is returned. If requireProjectCommand is true, + * then a PROJECT(Project) command will be added to the file + * if it does not have a PROJECT command in it. */ - cmListFile* GetFileCache(const char* path); + cmListFile* GetFileCache(const char* path, bool requireProjectCommand); //! Flush cache file out of cache. void FlushCache(const char* path); private: // Cache the file - bool CacheFile(const char* path); + bool CacheFile(const char* path, bool requireProjectCommand); // private data typedef std::map ListFileMap; ListFileMap m_ListFileCache; // file name to ListFile map diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index d180b84d1..dcb47f874 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -308,9 +308,26 @@ bool cmMakefile::ReadListFile(const char* filename, const char* external) { filenametoread= external; } - + // try to see if the list file is the top most + // list file for a project, and if it is, then it + // must have a project command. If there is not + // one, then cmake will provide one via the + // cmListFileCache class. + bool requireProjectCommand = false; + if(!m_Inheriting && !external + && m_cmCurrentDirectory == m_cmHomeDirectory) + { + if(cmSystemTools::LowerCase( + cmSystemTools::GetFilenameName(filename)) == "cmakelists.txt") + { + requireProjectCommand = true; + std::cerr << "Require project command " << filename << "\n"; + } + } + cmListFile* lf = - cmListFileCache::GetInstance()->GetFileCache(filenametoread); + cmListFileCache::GetInstance()->GetFileCache(filenametoread, + requireProjectCommand); if(!lf) { return false;