cmake/Source/cmMessageCommand.cxx

256 lines
7.0 KiB
C++
Raw Normal View History

2016-10-30 18:24:19 +01:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMessageCommand.h"
2020-02-01 23:06:01 +01:00
#include <cassert>
2023-07-02 19:51:09 +02:00
#include <memory>
2020-08-30 11:54:41 +02:00
#include <utility>
#include <cm/string_view>
#include <cmext/string_view>
2020-02-01 23:06:01 +01:00
2023-05-23 16:38:00 +02:00
#include "cmConfigureLog.h"
2020-02-01 23:06:01 +01:00
#include "cmExecutionStatus.h"
2023-07-02 19:51:09 +02:00
#include "cmList.h"
2017-04-14 19:02:05 +02:00
#include "cmMakefile.h"
2019-11-11 23:01:05 +01:00
#include "cmMessageType.h"
2016-10-30 18:24:19 +01:00
#include "cmMessenger.h"
2019-11-11 23:01:05 +01:00
#include "cmRange.h"
2020-02-01 23:06:01 +01:00
#include "cmStringAlgorithms.h"
2017-04-14 19:02:05 +02:00
#include "cmSystemTools.h"
#include "cmake.h"
2023-07-02 19:51:09 +02:00
#ifdef CMake_ENABLE_DEBUGGER
# include "cmDebuggerAdapter.h"
#endif
2020-08-30 11:54:41 +02:00
namespace {
enum class CheckingType
{
UNDEFINED,
CHECK_START,
CHECK_PASS,
CHECK_FAIL
};
std::string IndentText(std::string text, cmMakefile& mf)
{
auto indent =
2023-07-02 19:51:09 +02:00
cmList{ mf.GetSafeDefinition("CMAKE_MESSAGE_INDENT") }.join("");
2020-08-30 11:54:41 +02:00
const auto showContext = mf.GetCMakeInstance()->GetShowLogContext() ||
mf.IsOn("CMAKE_MESSAGE_CONTEXT_SHOW");
if (showContext) {
2023-07-02 19:51:09 +02:00
auto context =
cmList{ mf.GetSafeDefinition("CMAKE_MESSAGE_CONTEXT") }.join(".");
2020-08-30 11:54:41 +02:00
if (!context.empty()) {
indent.insert(0u, cmStrCat("["_s, context, "] "_s));
}
}
if (!indent.empty()) {
cmSystemTools::ReplaceString(text, "\n", "\n" + indent);
text.insert(0u, indent);
}
return text;
}
void ReportCheckResult(cm::string_view what, std::string result,
cmMakefile& mf)
{
if (mf.GetCMakeInstance()->HasCheckInProgress()) {
auto text = mf.GetCMakeInstance()->GetTopCheckInProgressMessage() + " - " +
std::move(result);
mf.DisplayStatus(IndentText(std::move(text), mf), -1);
} else {
mf.GetMessenger()->DisplayMessage(
MessageType::AUTHOR_WARNING,
cmStrCat("Ignored "_s, what, " without CHECK_START"_s),
mf.GetBacktrace());
}
}
2023-05-23 16:38:00 +02:00
namespace {
#ifndef CMAKE_BOOTSTRAP
void WriteMessageEvent(cmConfigureLog& log, cmMakefile const& mf,
std::string const& message)
{
// Keep in sync with cmFileAPIConfigureLog's DumpEventKindNames.
static const std::vector<unsigned long> LogVersionsWithMessageV1{ 1 };
if (log.IsAnyLogVersionEnabled(LogVersionsWithMessageV1)) {
log.BeginEvent("message-v1", mf);
log.WriteLiteralTextBlock("message"_s, message);
log.EndEvent();
}
}
#endif
}
2020-08-30 11:54:41 +02:00
} // anonymous namespace
// cmLibraryCommand
2020-02-01 23:06:01 +01:00
bool cmMessageCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
2016-10-30 18:24:19 +01:00
if (args.empty()) {
2020-02-01 23:06:01 +01:00
status.SetError("called with incorrect number of arguments");
return false;
2016-07-09 11:21:54 +02:00
}
2020-08-30 11:54:41 +02:00
auto& mf = status.GetMakefile();
2019-11-11 23:01:05 +01:00
auto i = args.cbegin();
2019-11-11 23:01:05 +01:00
auto type = MessageType::MESSAGE;
auto fatal = false;
2022-11-16 20:14:03 +01:00
auto level = Message::LogLevel::LOG_UNDEFINED;
2020-08-30 11:54:41 +02:00
auto checkingType = CheckingType::UNDEFINED;
2016-07-09 11:21:54 +02:00
if (*i == "SEND_ERROR") {
2019-11-11 23:01:05 +01:00
type = MessageType::FATAL_ERROR;
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_ERROR;
++i;
2016-07-09 11:21:54 +02:00
} else if (*i == "FATAL_ERROR") {
2009-10-04 10:30:41 +03:00
fatal = true;
2019-11-11 23:01:05 +01:00
type = MessageType::FATAL_ERROR;
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_ERROR;
2009-10-04 10:30:41 +03:00
++i;
2016-07-09 11:21:54 +02:00
} else if (*i == "WARNING") {
2019-11-11 23:01:05 +01:00
type = MessageType::WARNING;
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_WARNING;
2009-10-04 10:30:41 +03:00
++i;
2016-07-09 11:21:54 +02:00
} else if (*i == "AUTHOR_WARNING") {
2020-08-30 11:54:41 +02:00
if (mf.IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") &&
!mf.IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS")) {
2016-03-13 13:35:51 +01:00
fatal = true;
2019-11-11 23:01:05 +01:00
type = MessageType::AUTHOR_ERROR;
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_ERROR;
2020-08-30 11:54:41 +02:00
} else if (!mf.IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) {
2019-11-11 23:01:05 +01:00
type = MessageType::AUTHOR_WARNING;
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_WARNING;
2016-07-09 11:21:54 +02:00
} else {
2016-03-13 13:35:51 +01:00
return true;
2009-10-04 10:30:41 +03:00
}
2016-07-09 11:21:54 +02:00
++i;
2020-08-30 11:54:41 +02:00
} else if (*i == "CHECK_START") {
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_STATUS;
2020-08-30 11:54:41 +02:00
checkingType = CheckingType::CHECK_START;
++i;
} else if (*i == "CHECK_PASS") {
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_STATUS;
2020-08-30 11:54:41 +02:00
checkingType = CheckingType::CHECK_PASS;
++i;
} else if (*i == "CHECK_FAIL") {
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_STATUS;
2020-08-30 11:54:41 +02:00
checkingType = CheckingType::CHECK_FAIL;
++i;
2023-05-23 16:38:00 +02:00
} else if (*i == "CONFIGURE_LOG") {
#ifndef CMAKE_BOOTSTRAP
if (cmConfigureLog* log = mf.GetCMakeInstance()->GetConfigureLog()) {
++i;
WriteMessageEvent(*log, mf, cmJoin(cmMakeRange(i, args.cend()), ""_s));
}
#endif
return true;
2016-07-09 11:21:54 +02:00
} else if (*i == "STATUS") {
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_STATUS;
2019-11-11 23:01:05 +01:00
++i;
} else if (*i == "VERBOSE") {
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_VERBOSE;
2019-11-11 23:01:05 +01:00
++i;
} else if (*i == "DEBUG") {
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_DEBUG;
2019-11-11 23:01:05 +01:00
++i;
} else if (*i == "TRACE") {
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_TRACE;
2009-10-04 10:30:41 +03:00
++i;
2016-07-09 11:21:54 +02:00
} else if (*i == "DEPRECATION") {
2020-08-30 11:54:41 +02:00
if (mf.IsOn("CMAKE_ERROR_DEPRECATED")) {
2014-08-03 19:52:23 +02:00
fatal = true;
2019-11-11 23:01:05 +01:00
type = MessageType::DEPRECATION_ERROR;
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_ERROR;
2020-08-30 11:54:41 +02:00
} else if (!mf.IsSet("CMAKE_WARN_DEPRECATED") ||
mf.IsOn("CMAKE_WARN_DEPRECATED")) {
2019-11-11 23:01:05 +01:00
type = MessageType::DEPRECATION_WARNING;
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_WARNING;
2016-07-09 11:21:54 +02:00
} else {
2014-08-03 19:52:23 +02:00
return true;
}
2016-07-09 11:21:54 +02:00
++i;
2019-11-11 23:01:05 +01:00
} else if (*i == "NOTICE") {
// `NOTICE` message type is going to be output to stderr
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_NOTICE;
2019-11-11 23:01:05 +01:00
++i;
} else {
// Messages w/o any type are `NOTICE`s
2022-11-16 20:14:03 +01:00
level = Message::LogLevel::LOG_NOTICE;
2019-11-11 23:01:05 +01:00
}
assert("Message log level expected to be set" &&
2022-11-16 20:14:03 +01:00
level != Message::LogLevel::LOG_UNDEFINED);
Message::LogLevel desiredLevel = mf.GetCurrentLogLevel();
2020-08-30 11:54:41 +02:00
2019-11-11 23:01:05 +01:00
if (desiredLevel < level) {
// Suppress the message
return true;
2016-07-09 11:21:54 +02:00
}
2019-11-11 23:01:05 +01:00
auto message = cmJoin(cmMakeRange(i, args.cend()), "");
2020-02-01 23:06:01 +01:00
switch (level) {
2022-11-16 20:14:03 +01:00
case Message::LogLevel::LOG_ERROR:
case Message::LogLevel::LOG_WARNING:
2020-02-01 23:06:01 +01:00
// we've overridden the message type, above, so display it directly
2020-08-30 11:54:41 +02:00
mf.GetMessenger()->DisplayMessage(type, message, mf.GetBacktrace());
2020-02-01 23:06:01 +01:00
break;
2022-11-16 20:14:03 +01:00
case Message::LogLevel::LOG_NOTICE:
2020-08-30 11:54:41 +02:00
cmSystemTools::Message(IndentText(message, mf));
2023-07-02 19:51:09 +02:00
#ifdef CMake_ENABLE_DEBUGGER
if (mf.GetCMakeInstance()->GetDebugAdapter() != nullptr) {
mf.GetCMakeInstance()->GetDebugAdapter()->OnMessageOutput(type,
message);
}
#endif
2020-02-01 23:06:01 +01:00
break;
2022-11-16 20:14:03 +01:00
case Message::LogLevel::LOG_STATUS:
2020-08-30 11:54:41 +02:00
switch (checkingType) {
case CheckingType::CHECK_START:
mf.DisplayStatus(IndentText(message, mf), -1);
mf.GetCMakeInstance()->PushCheckInProgressMessage(message);
break;
case CheckingType::CHECK_PASS:
ReportCheckResult("CHECK_PASS"_s, message, mf);
break;
case CheckingType::CHECK_FAIL:
ReportCheckResult("CHECK_FAIL"_s, message, mf);
break;
default:
mf.DisplayStatus(IndentText(message, mf), -1);
break;
}
break;
2022-11-16 20:14:03 +01:00
case Message::LogLevel::LOG_VERBOSE:
case Message::LogLevel::LOG_DEBUG:
case Message::LogLevel::LOG_TRACE:
2020-08-30 11:54:41 +02:00
mf.DisplayStatus(IndentText(message, mf), -1);
2020-02-01 23:06:01 +01:00
break;
default:
assert("Unexpected log level! Review the `cmMessageCommand.cxx`." &&
false);
break;
2016-07-09 11:21:54 +02:00
}
2020-02-01 23:06:01 +01:00
2016-07-09 11:21:54 +02:00
if (fatal) {
2022-08-04 22:12:04 +02:00
cmSystemTools::SetFatalErrorOccurred();
2016-07-09 11:21:54 +02:00
}
return true;
}