cmDepends.cxx 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmDepends.h"
  14. #include "cmGeneratedFileStream.h"
  15. #include "cmSystemTools.h"
  16. #include "cmFileTimeComparison.h"
  17. #include <string.h>
  18. //----------------------------------------------------------------------------
  19. cmDepends::cmDepends():
  20. CompileDirectory(),
  21. LocalGenerator(0),
  22. Verbose(false),
  23. FileComparison(0),
  24. MaxPath(cmSystemTools::GetMaximumFilePathLength()),
  25. Dependee(new char[MaxPath]),
  26. Depender(new char[MaxPath])
  27. {
  28. }
  29. //----------------------------------------------------------------------------
  30. cmDepends::~cmDepends()
  31. {
  32. delete [] this->Dependee;
  33. delete [] this->Depender;
  34. }
  35. //----------------------------------------------------------------------------
  36. bool cmDepends::Write(const char *src, const char *obj,
  37. std::ostream &makeDepends, std::ostream &internalDepends)
  38. {
  39. return this->WriteDependencies(src, obj, makeDepends, internalDepends);
  40. }
  41. //----------------------------------------------------------------------------
  42. void cmDepends::Check(const char *makeFile, const char *internalFile)
  43. {
  44. // Dependency checks must be done in proper working directory.
  45. std::string oldcwd = ".";
  46. if(this->CompileDirectory != ".")
  47. {
  48. // Get the CWD but do not call CollapseFullPath because
  49. // we only need it to cd back, and the form does not matter
  50. oldcwd = cmSystemTools::GetCurrentWorkingDirectory(false);
  51. cmSystemTools::ChangeDirectory(this->CompileDirectory.c_str());
  52. }
  53. // Check whether dependencies must be regenerated.
  54. std::ifstream fin(internalFile);
  55. if(!(fin && this->CheckDependencies(fin)))
  56. {
  57. // Clear all dependencies so they will be regenerated.
  58. this->Clear(makeFile);
  59. this->Clear(internalFile);
  60. }
  61. // Restore working directory.
  62. if(oldcwd != ".")
  63. {
  64. cmSystemTools::ChangeDirectory(oldcwd.c_str());
  65. }
  66. }
  67. //----------------------------------------------------------------------------
  68. void cmDepends::Clear(const char *file)
  69. {
  70. // Print verbose output.
  71. if(this->Verbose)
  72. {
  73. cmOStringStream msg;
  74. msg << "Clearing dependencies in \"" << file << "\"." << std::endl;
  75. cmSystemTools::Stdout(msg.str().c_str());
  76. }
  77. // Remove the dependency mark file to be sure dependencies will be
  78. // regenerated.
  79. std::string markFile = file;
  80. markFile += ".mark";
  81. cmSystemTools::RemoveFile(markFile.c_str());
  82. // Write an empty dependency file.
  83. cmGeneratedFileStream depFileStream(file);
  84. depFileStream
  85. << "# Empty dependencies file\n"
  86. << "# This may be replaced when dependencies are built." << std::endl;
  87. }
  88. //----------------------------------------------------------------------------
  89. bool cmDepends::CheckDependencies(std::istream& internalDepends)
  90. {
  91. // Parse dependencies from the stream. If any dependee is missing
  92. // or newer than the depender then dependencies should be
  93. // regenerated.
  94. bool okay = true;
  95. while(internalDepends.getline(this->Dependee, this->MaxPath))
  96. {
  97. if ( this->Dependee[0] == 0 || this->Dependee[0] == '#' ||
  98. this->Dependee[0] == '\r' )
  99. {
  100. continue;
  101. }
  102. size_t len = internalDepends.gcount()-1;
  103. if ( this->Dependee[len-1] == '\r' )
  104. {
  105. len --;
  106. this->Dependee[len] = 0;
  107. }
  108. if ( this->Dependee[0] != ' ' )
  109. {
  110. memcpy(this->Depender, this->Dependee, len+1);
  111. continue;
  112. }
  113. /*
  114. // Parse the dependency line.
  115. if(!this->ParseDependency(line.c_str()))
  116. {
  117. continue;
  118. }
  119. */
  120. // Dependencies must be regenerated if the dependee does not exist
  121. // or if the depender exists and is older than the dependee.
  122. bool regenerate = false;
  123. const char* dependee = this->Dependee+1;
  124. const char* depender = this->Depender;
  125. if(!cmSystemTools::FileExists(dependee))
  126. {
  127. // The dependee does not exist.
  128. regenerate = true;
  129. // Print verbose output.
  130. if(this->Verbose)
  131. {
  132. cmOStringStream msg;
  133. msg << "Dependee \"" << dependee
  134. << "\" does not exist for depender \""
  135. << depender << "\"." << std::endl;
  136. cmSystemTools::Stdout(msg.str().c_str());
  137. }
  138. }
  139. else if(cmSystemTools::FileExists(depender))
  140. {
  141. // The dependee and depender both exist. Compare file times.
  142. int result = 0;
  143. if((!this->FileComparison->FileTimeCompare(depender, dependee,
  144. &result) || result < 0))
  145. {
  146. // The depender is older than the dependee.
  147. regenerate = true;
  148. // Print verbose output.
  149. if(this->Verbose)
  150. {
  151. cmOStringStream msg;
  152. msg << "Dependee \"" << dependee
  153. << "\" is newer than depender \""
  154. << depender << "\"." << std::endl;
  155. cmSystemTools::Stdout(msg.str().c_str());
  156. }
  157. }
  158. }
  159. if(regenerate)
  160. {
  161. // Dependencies must be regenerated.
  162. okay = false;
  163. // Remove the depender to be sure it is rebuilt.
  164. cmSystemTools::RemoveFile(depender);
  165. }
  166. }
  167. return okay;
  168. }