cmMessageCommand.cxx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmMessageCommand.h"
  4. #include "cmMakefile.h"
  5. #include "cmMessageType.h"
  6. #include "cmMessenger.h"
  7. #include "cmRange.h"
  8. #include "cmStringAlgorithms.h"
  9. #include "cmSystemTools.h"
  10. #include "cmake.h"
  11. #include <cassert>
  12. class cmExecutionStatus;
  13. // cmLibraryCommand
  14. bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
  15. cmExecutionStatus&)
  16. {
  17. if (args.empty()) {
  18. this->SetError("called with incorrect number of arguments");
  19. return false;
  20. }
  21. auto i = args.cbegin();
  22. auto type = MessageType::MESSAGE;
  23. auto fatal = false;
  24. auto level = cmake::LogLevel::LOG_UNDEFINED;
  25. if (*i == "SEND_ERROR") {
  26. type = MessageType::FATAL_ERROR;
  27. level = cmake::LogLevel::LOG_ERROR;
  28. ++i;
  29. } else if (*i == "FATAL_ERROR") {
  30. fatal = true;
  31. type = MessageType::FATAL_ERROR;
  32. level = cmake::LogLevel::LOG_ERROR;
  33. ++i;
  34. } else if (*i == "WARNING") {
  35. type = MessageType::WARNING;
  36. level = cmake::LogLevel::LOG_WARNING;
  37. ++i;
  38. } else if (*i == "AUTHOR_WARNING") {
  39. if (this->Makefile->IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") &&
  40. !this->Makefile->IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS")) {
  41. fatal = true;
  42. type = MessageType::AUTHOR_ERROR;
  43. level = cmake::LogLevel::LOG_ERROR;
  44. } else if (!this->Makefile->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) {
  45. type = MessageType::AUTHOR_WARNING;
  46. level = cmake::LogLevel::LOG_WARNING;
  47. } else {
  48. return true;
  49. }
  50. ++i;
  51. } else if (*i == "STATUS") {
  52. level = cmake::LogLevel::LOG_STATUS;
  53. ++i;
  54. } else if (*i == "VERBOSE") {
  55. level = cmake::LogLevel::LOG_VERBOSE;
  56. ++i;
  57. } else if (*i == "DEBUG") {
  58. level = cmake::LogLevel::LOG_DEBUG;
  59. ++i;
  60. } else if (*i == "TRACE") {
  61. level = cmake::LogLevel::LOG_TRACE;
  62. ++i;
  63. } else if (*i == "DEPRECATION") {
  64. if (this->Makefile->IsOn("CMAKE_ERROR_DEPRECATED")) {
  65. fatal = true;
  66. type = MessageType::DEPRECATION_ERROR;
  67. level = cmake::LogLevel::LOG_ERROR;
  68. } else if ((!this->Makefile->IsSet("CMAKE_WARN_DEPRECATED") ||
  69. this->Makefile->IsOn("CMAKE_WARN_DEPRECATED"))) {
  70. type = MessageType::DEPRECATION_WARNING;
  71. level = cmake::LogLevel::LOG_WARNING;
  72. } else {
  73. return true;
  74. }
  75. ++i;
  76. } else if (*i == "NOTICE") {
  77. // `NOTICE` message type is going to be output to stderr
  78. level = cmake::LogLevel::LOG_NOTICE;
  79. ++i;
  80. } else {
  81. // Messages w/o any type are `NOTICE`s
  82. level = cmake::LogLevel::LOG_NOTICE;
  83. }
  84. assert("Message log level expected to be set" &&
  85. level != cmake::LogLevel::LOG_UNDEFINED);
  86. auto desiredLevel = this->Makefile->GetCMakeInstance()->GetLogLevel();
  87. assert("Expected a valid log level here" &&
  88. desiredLevel != cmake::LogLevel::LOG_UNDEFINED);
  89. if (desiredLevel < level) {
  90. // Suppress the message
  91. return true;
  92. }
  93. auto message = cmJoin(cmMakeRange(i, args.cend()), "");
  94. if (cmake::LogLevel::LOG_NOTICE <= level) {
  95. // Check if any indentation has requested:
  96. // `CMAKE_MESSAGE_INDENT` is a list of "padding" pieces
  97. // to be joined and prepended to the message lines.
  98. auto indent = cmJoin(cmExpandedList(this->Makefile->GetSafeDefinition(
  99. "CMAKE_MESSAGE_INDENT")),
  100. "");
  101. // Make every line of the `message` indented
  102. // NOTE Can't reuse `cmDocumentationFormatter::PrintPreformatted`
  103. // here cuz it appends `\n` to the EOM ;-(
  104. cmSystemTools::ReplaceString(message, "\n", "\n" + indent);
  105. message = indent + message;
  106. }
  107. switch (level) {
  108. case cmake::LogLevel::LOG_ERROR:
  109. case cmake::LogLevel::LOG_WARNING:
  110. // we've overridden the message type, above, so display it directly
  111. this->Makefile->GetMessenger()->DisplayMessage(
  112. type, message, this->Makefile->GetBacktrace());
  113. break;
  114. case cmake::LogLevel::LOG_NOTICE:
  115. cmSystemTools::Message(message);
  116. break;
  117. case cmake::LogLevel::LOG_STATUS:
  118. case cmake::LogLevel::LOG_VERBOSE:
  119. case cmake::LogLevel::LOG_DEBUG:
  120. case cmake::LogLevel::LOG_TRACE:
  121. this->Makefile->DisplayStatus(message, -1);
  122. break;
  123. default:
  124. assert("Unexpected log level! Review the `cmMessageCommand.cxx`." &&
  125. false);
  126. break;
  127. }
  128. if (fatal) {
  129. cmSystemTools::SetFatalErrorOccured();
  130. }
  131. return true;
  132. }