cmDepends.cxx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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(): Verbose(false), FileComparison(0),
  20. MaxPath(cmSystemTools::GetMaximumFilePathLength()),
  21. Dependee(new char[MaxPath]),
  22. Depender(new char[MaxPath])
  23. {
  24. }
  25. //----------------------------------------------------------------------------
  26. cmDepends::~cmDepends()
  27. {
  28. delete [] this->Dependee;
  29. delete [] this->Depender;
  30. }
  31. //----------------------------------------------------------------------------
  32. bool cmDepends::Write(const char *src, const char *obj,
  33. std::ostream &makeDepends, std::ostream &internalDepends)
  34. {
  35. return this->WriteDependencies(src, obj, makeDepends, internalDepends);
  36. }
  37. //----------------------------------------------------------------------------
  38. void cmDepends::Check(const char *makeFile, const char *internalFile)
  39. {
  40. // Dependency checks must be done in proper working directory.
  41. std::string oldcwd = ".";
  42. if(this->CompileDirectory != ".")
  43. {
  44. // Get the CWD but do not call CollapseFullPath because
  45. // we only need it to cd back, and the form does not matter
  46. oldcwd = cmSystemTools::GetCurrentWorkingDirectory(false);
  47. cmSystemTools::ChangeDirectory(this->CompileDirectory.c_str());
  48. }
  49. // Check whether dependencies must be regenerated.
  50. std::ifstream fin(internalFile);
  51. if(!(fin && this->CheckDependencies(fin)))
  52. {
  53. // Clear all dependencies so they will be regenerated.
  54. this->Clear(makeFile);
  55. this->Clear(internalFile);
  56. }
  57. // Restore working directory.
  58. if(oldcwd != ".")
  59. {
  60. cmSystemTools::ChangeDirectory(oldcwd.c_str());
  61. }
  62. }
  63. //----------------------------------------------------------------------------
  64. void cmDepends::Clear(const char *file)
  65. {
  66. // Print verbose output.
  67. if(this->Verbose)
  68. {
  69. cmOStringStream msg;
  70. msg << "Clearing dependencies in \"" << file << "\"." << std::endl;
  71. cmSystemTools::Stdout(msg.str().c_str());
  72. }
  73. // Remove the dependency mark file to be sure dependencies will be
  74. // regenerated.
  75. std::string markFile = file;
  76. markFile += ".mark";
  77. cmSystemTools::RemoveFile(markFile.c_str());
  78. // Write an empty dependency file.
  79. cmGeneratedFileStream depFileStream(file);
  80. depFileStream
  81. << "# Empty dependencies file\n"
  82. << "# This may be replaced when dependencies are built." << std::endl;
  83. }
  84. //----------------------------------------------------------------------------
  85. bool cmDepends::CheckDependencies(std::istream& internalDepends)
  86. {
  87. // Parse dependencies from the stream. If any dependee is missing
  88. // or newer than the depender then dependencies should be
  89. // regenerated.
  90. bool okay = true;
  91. while(internalDepends.getline(this->Dependee, this->MaxPath))
  92. {
  93. if ( this->Dependee[0] == 0 || this->Dependee[0] == '#' || this->Dependee[0] == '\r' )
  94. {
  95. continue;
  96. }
  97. size_t len = internalDepends.gcount()-1;
  98. if ( this->Dependee[len-1] == '\r' )
  99. {
  100. len --;
  101. this->Dependee[len] = 0;
  102. }
  103. if ( this->Dependee[0] != ' ' )
  104. {
  105. memcpy(this->Depender, this->Dependee, len+1);
  106. continue;
  107. }
  108. /*
  109. // Parse the dependency line.
  110. if(!this->ParseDependency(line.c_str()))
  111. {
  112. continue;
  113. }
  114. */
  115. // Dependencies must be regenerated if the dependee does not exist
  116. // or if the depender exists and is older than the dependee.
  117. bool regenerate = false;
  118. const char* dependee = this->Dependee+1;
  119. const char* depender = this->Depender;
  120. if(!cmSystemTools::FileExists(dependee))
  121. {
  122. // The dependee does not exist.
  123. regenerate = true;
  124. // Print verbose output.
  125. if(this->Verbose)
  126. {
  127. cmOStringStream msg;
  128. msg << "Dependee \"" << dependee
  129. << "\" does not exist for depender \""
  130. << depender << "\"." << std::endl;
  131. cmSystemTools::Stdout(msg.str().c_str());
  132. }
  133. }
  134. else if(cmSystemTools::FileExists(depender))
  135. {
  136. // The dependee and depender both exist. Compare file times.
  137. int result = 0;
  138. if((!this->FileComparison->FileTimeCompare(depender, dependee,
  139. &result) || result < 0))
  140. {
  141. // The depender is older than the dependee.
  142. regenerate = true;
  143. // Print verbose output.
  144. if(this->Verbose)
  145. {
  146. cmOStringStream msg;
  147. msg << "Dependee \"" << dependee
  148. << "\" is newer than depender \""
  149. << depender << "\"." << std::endl;
  150. cmSystemTools::Stdout(msg.str().c_str());
  151. }
  152. }
  153. }
  154. if(regenerate)
  155. {
  156. // Dependencies must be regenerated.
  157. okay = false;
  158. // Remove the depender to be sure it is rebuilt.
  159. cmSystemTools::RemoveFile(depender);
  160. }
  161. }
  162. return okay;
  163. }