diff options
author | Andy Cedilnik <andy.cedilnik@kitware.com> | 2004-04-18 18:41:46 (GMT) |
---|---|---|
committer | Andy Cedilnik <andy.cedilnik@kitware.com> | 2004-04-18 18:41:46 (GMT) |
commit | 55a71ba572c54dbb3485a76e9615c1c8bf688fd4 (patch) | |
tree | ac692b4ef198284cf7c0e9b65ab854f93e7f865a /Source | |
parent | af61b685839fae6af72ba4c4d42ebf39a7d1a324 (diff) | |
download | CMake-55a71ba572c54dbb3485a76e9615c1c8bf688fd4.zip CMake-55a71ba572c54dbb3485a76e9615c1c8bf688fd4.tar.gz CMake-55a71ba572c54dbb3485a76e9615c1c8bf688fd4.tar.bz2 |
ENH: Add check for infinite loops. Make sure that files written using WRITE_FILE and FILE WRITE are not used as input files. Fixes Bug #678 - WRITE_FILE and FILE(WRITE...) lead to infinite loops
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmFileCommand.cxx | 1 | ||||
-rw-r--r-- | Source/cmFileCommand.h | 4 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 1 | ||||
-rw-r--r-- | Source/cmMakefile.cxx | 21 | ||||
-rw-r--r-- | Source/cmMakefile.h | 12 | ||||
-rw-r--r-- | Source/cmWriteFileCommand.cxx | 1 | ||||
-rw-r--r-- | Source/cmWriteFileCommand.h | 8 | ||||
-rw-r--r-- | Source/cmake.cxx | 10 | ||||
-rw-r--r-- | Source/cmake.h | 8 |
9 files changed, 64 insertions, 2 deletions
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 04608b5..ecac040 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -100,6 +100,7 @@ bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args, } file << message; file.close(); + m_Makefile->AddWrittenFile(fileName.c_str()); return true; } diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index 60e25e8..5d00acf 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -81,6 +81,10 @@ public: "if it does not exists.\n" "APPEND will write a message into a file same as WRITE, except " "it will append it to the end of the file\n" + "NOTE: When using FILE WRITE and FILE APPEND, the produced file " + "cannot be used as an input to CMake (CONFIGURE_FILE, source file ...) " + "because it will lead to infinite loop. Use CONFIGURE_FILE if you " + "want to generate input files to CMake.\n" "READ will read the content of a file and store it into the " "variable.\n" "GLOB will generate a list of all files that match the globbing " diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index b09ab9d..1315bb6 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -326,6 +326,7 @@ void cmGlobalGenerator::Configure() } m_CMakeInstance->UpdateProgress("Configuring", 0.9f+0.1f*(i+1.0f)/m_LocalGenerators.size()); + m_LocalGenerators[i]->GetMakefile()->CheckInfiniteLoops(); } } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 4f287f6..59b270a 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -2357,5 +2357,26 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile, return 1; } +void cmMakefile::AddWrittenFile(const char* file) +{ this->GetCMakeInstance()->AddWrittenFile(file); } +bool cmMakefile::HasWrittenFile(const char* file) +{ return this->GetCMakeInstance()->HasWrittenFile(file); } +bool cmMakefile::CheckInfiniteLoops() +{ + std::vector<std::string>::iterator it; + for ( it = m_ListFiles.begin(); + it != m_ListFiles.end(); + ++ it ) + { + if ( this->HasWrittenFile(it->c_str()) ) + { + cmOStringStream str; + str << "File " << it->c_str() << " is written by WRITE_FILE (or FILE WRITE) command and should not be used as input to CMake. Please use CONFIGURE_FILE to be safe. Refer to the note next to FILE WRITE command."; + cmSystemTools::Error(str.str().c_str()); + return false; + } + } + return true; +} diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 092d742..194729e 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -82,6 +82,18 @@ public: void RemoveFunctionBlocker(cmFunctionBlocker *fb) { m_FunctionBlockers.remove(fb);} void RemoveFunctionBlocker(const cmListFileFunction& lff); + + /** + * Add file to the written file list. These file should not be in the list + * of dependencies because they cause infinite loops. + */ + void AddWrittenFile(const char* file); + bool HasWrittenFile(const char* file); + + /** + * Check if there are any infinite loops + */ + bool CheckInfiniteLoops(); /** * Try running cmake and building a file. This is used for dynalically diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx index 79a8b46..dbf14ec 100644 --- a/Source/cmWriteFileCommand.cxx +++ b/Source/cmWriteFileCommand.cxx @@ -55,6 +55,7 @@ bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args) } file << message << std::endl; file.close(); + m_Makefile->AddWrittenFile(fileName.c_str()); return true; } diff --git a/Source/cmWriteFileCommand.h b/Source/cmWriteFileCommand.h index ef2561d..31e1687 100644 --- a/Source/cmWriteFileCommand.h +++ b/Source/cmWriteFileCommand.h @@ -67,7 +67,13 @@ public: " WRITE_FILE(filename \"message to write\"... [APPEND])\n" "The first argument is the file name, the rest of the arguments are " "messages to write. If the argument APPEND is specified, then " - "the message will be appended."; + "the message will be appended.\n" + "NOTE 1: FILE WRITE and FILE APPEND do exactly the same as this one " + "but add some more functionality.\n" + "NOTE 2: When using WRITE_FILE the produced file cannot be used as an " + "input to CMake (CONFIGURE_FILE, source file ...) because it will " + "lead to infinite loop. Use CONFIGURE_FILE if you want to generate " + "input files to CMake."; } cmTypeMacro(cmWriteFileCommand, cmCommand); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 5ce680e..a49559b 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -1416,3 +1416,13 @@ void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v) cmDocumentationEntry empty = {0,0,0}; v.push_back(empty); } + +void cmake::AddWrittenFile(const char* file) +{ + m_WrittenFiles.insert(file); +} + +bool cmake::HasWrittenFile(const char* file) +{ + return m_WrittenFiles.find(file) != m_WrittenFiles.end(); +} diff --git a/Source/cmake.h b/Source/cmake.h index 833b454..dc79604 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -257,7 +257,11 @@ class cmake ///! Debug the try compile stuff by not delelting the files bool GetDebugTryCompile(){return m_DebugTryCompile;} void DebugTryCompileOn(){m_DebugTryCompile = true;} - + + ///! Get the list of files written by CMake using FILE(WRITE / WRITE_FILE + void AddWrittenFile(const char* file); + bool HasWrittenFile(const char* file); + protected: typedef cmGlobalGenerator* (*CreateGeneratorFunctionType)(); typedef std::map<cmStdString, CreateGeneratorFunctionType> RegisteredGeneratorsMap; @@ -273,6 +277,8 @@ protected: std::string m_cmStartDirectory; std::string m_StartOutputDirectory; + std::set<cmStdString> m_WrittenFiles; + ///! return true if the same cmake was used to make the cache. bool CacheVersionMatches(); ///! read in a cmake list file to initialize the cache |