cmMessenger.cxx 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmMessenger.h"
  11. #include "cmDocumentationFormatter.h"
  12. #include "cmMessenger.h"
  13. #include "cmOutputConverter.h"
  14. #if defined(CMAKE_BUILD_WITH_CMAKE)
  15. #include <cmsys/SystemInformation.hxx>
  16. #endif
  17. cmake::MessageType cmMessenger::ConvertMessageType(cmake::MessageType t) const
  18. {
  19. bool warningsAsErrors;
  20. if (t == cmake::AUTHOR_WARNING || t == cmake::AUTHOR_ERROR) {
  21. warningsAsErrors = this->GetDevWarningsAsErrors();
  22. if (warningsAsErrors && t == cmake::AUTHOR_WARNING) {
  23. t = cmake::AUTHOR_ERROR;
  24. } else if (!warningsAsErrors && t == cmake::AUTHOR_ERROR) {
  25. t = cmake::AUTHOR_WARNING;
  26. }
  27. } else if (t == cmake::DEPRECATION_WARNING ||
  28. t == cmake::DEPRECATION_ERROR) {
  29. warningsAsErrors = this->GetDeprecatedWarningsAsErrors();
  30. if (warningsAsErrors && t == cmake::DEPRECATION_WARNING) {
  31. t = cmake::DEPRECATION_ERROR;
  32. } else if (!warningsAsErrors && t == cmake::DEPRECATION_ERROR) {
  33. t = cmake::DEPRECATION_WARNING;
  34. }
  35. }
  36. return t;
  37. }
  38. bool cmMessenger::IsMessageTypeVisible(cmake::MessageType t) const
  39. {
  40. bool isVisible = true;
  41. if (t == cmake::DEPRECATION_ERROR) {
  42. if (!this->GetDeprecatedWarningsAsErrors()) {
  43. isVisible = false;
  44. }
  45. } else if (t == cmake::DEPRECATION_WARNING) {
  46. if (this->GetSuppressDeprecatedWarnings()) {
  47. isVisible = false;
  48. }
  49. } else if (t == cmake::AUTHOR_ERROR) {
  50. if (!this->GetDevWarningsAsErrors()) {
  51. isVisible = false;
  52. }
  53. } else if (t == cmake::AUTHOR_WARNING) {
  54. if (this->GetSuppressDevWarnings()) {
  55. isVisible = false;
  56. }
  57. }
  58. return isVisible;
  59. }
  60. static bool printMessagePreamble(cmake::MessageType t, std::ostream& msg)
  61. {
  62. // Construct the message header.
  63. if (t == cmake::FATAL_ERROR) {
  64. msg << "CMake Error";
  65. } else if (t == cmake::INTERNAL_ERROR) {
  66. msg << "CMake Internal Error (please report a bug)";
  67. } else if (t == cmake::LOG) {
  68. msg << "CMake Debug Log";
  69. } else if (t == cmake::DEPRECATION_ERROR) {
  70. msg << "CMake Deprecation Error";
  71. } else if (t == cmake::DEPRECATION_WARNING) {
  72. msg << "CMake Deprecation Warning";
  73. } else if (t == cmake::AUTHOR_WARNING) {
  74. msg << "CMake Warning (dev)";
  75. } else if (t == cmake::AUTHOR_ERROR) {
  76. msg << "CMake Error (dev)";
  77. } else {
  78. msg << "CMake Warning";
  79. }
  80. return true;
  81. }
  82. void printMessageText(std::ostream& msg, std::string const& text)
  83. {
  84. msg << ":\n";
  85. cmDocumentationFormatter formatter;
  86. formatter.SetIndent(" ");
  87. formatter.PrintFormatted(msg, text.c_str());
  88. }
  89. void displayMessage(cmake::MessageType t, std::ostringstream& msg)
  90. {
  91. // Add a note about warning suppression.
  92. if (t == cmake::AUTHOR_WARNING) {
  93. msg << "This warning is for project developers. Use -Wno-dev to suppress "
  94. "it.";
  95. } else if (t == cmake::AUTHOR_ERROR) {
  96. msg << "This error is for project developers. Use -Wno-error=dev to "
  97. "suppress "
  98. "it.";
  99. }
  100. // Add a terminating blank line.
  101. msg << "\n";
  102. #if defined(CMAKE_BUILD_WITH_CMAKE)
  103. // Add a C++ stack trace to internal errors.
  104. if (t == cmake::INTERNAL_ERROR) {
  105. std::string stack = cmsys::SystemInformation::GetProgramStack(0, 0);
  106. if (!stack.empty()) {
  107. if (cmHasLiteralPrefix(stack, "WARNING:")) {
  108. stack = "Note:" + stack.substr(8);
  109. }
  110. msg << stack << "\n";
  111. }
  112. }
  113. #endif
  114. // Output the message.
  115. if (t == cmake::FATAL_ERROR || t == cmake::INTERNAL_ERROR ||
  116. t == cmake::DEPRECATION_ERROR || t == cmake::AUTHOR_ERROR) {
  117. cmSystemTools::SetErrorOccured();
  118. cmSystemTools::Message(msg.str().c_str(), "Error");
  119. } else {
  120. cmSystemTools::Message(msg.str().c_str(), "Warning");
  121. }
  122. }
  123. cmMessenger::cmMessenger(cmState* state)
  124. : State(state)
  125. {
  126. }
  127. void cmMessenger::IssueMessage(cmake::MessageType t, const std::string& text,
  128. const cmListFileBacktrace& backtrace) const
  129. {
  130. bool force = false;
  131. if (!force) {
  132. // override the message type, if needed, for warnings and errors
  133. cmake::MessageType override = this->ConvertMessageType(t);
  134. if (override != t) {
  135. t = override;
  136. force = true;
  137. }
  138. }
  139. if (!force && !this->IsMessageTypeVisible(t)) {
  140. return;
  141. }
  142. this->DisplayMessage(t, text, backtrace);
  143. }
  144. void cmMessenger::DisplayMessage(cmake::MessageType t, const std::string& text,
  145. const cmListFileBacktrace& backtrace) const
  146. {
  147. std::ostringstream msg;
  148. if (!printMessagePreamble(t, msg)) {
  149. return;
  150. }
  151. // Add the immediate context.
  152. backtrace.PrintTitle(msg);
  153. printMessageText(msg, text);
  154. // Add the rest of the context.
  155. backtrace.PrintCallStack(msg);
  156. displayMessage(t, msg);
  157. }
  158. bool cmMessenger::GetSuppressDevWarnings() const
  159. {
  160. const char* cacheEntryValue =
  161. this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
  162. return cmSystemTools::IsOn(cacheEntryValue);
  163. }
  164. bool cmMessenger::GetSuppressDeprecatedWarnings() const
  165. {
  166. const char* cacheEntryValue =
  167. this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
  168. return cacheEntryValue && cmSystemTools::IsOff(cacheEntryValue);
  169. }
  170. bool cmMessenger::GetDevWarningsAsErrors() const
  171. {
  172. const char* cacheEntryValue =
  173. this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_ERRORS");
  174. return cacheEntryValue && cmSystemTools::IsOff(cacheEntryValue);
  175. }
  176. bool cmMessenger::GetDeprecatedWarningsAsErrors() const
  177. {
  178. const char* cacheEntryValue =
  179. this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
  180. return cmSystemTools::IsOn(cacheEntryValue);
  181. }