CMake/Source/cmMessenger.cxx

204 lines
5.6 KiB
C++

/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMessenger.h"
#include "cmAlgorithms.h"
#include "cmDocumentationFormatter.h"
#include "cmState.h"
#include "cmSystemTools.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
#include <cmsys/SystemInformation.hxx>
#endif
#include <sstream>
cmake::MessageType cmMessenger::ConvertMessageType(cmake::MessageType t) const
{
bool warningsAsErrors;
if (t == cmake::AUTHOR_WARNING || t == cmake::AUTHOR_ERROR) {
warningsAsErrors = this->GetDevWarningsAsErrors();
if (warningsAsErrors && t == cmake::AUTHOR_WARNING) {
t = cmake::AUTHOR_ERROR;
} else if (!warningsAsErrors && t == cmake::AUTHOR_ERROR) {
t = cmake::AUTHOR_WARNING;
}
} else if (t == cmake::DEPRECATION_WARNING ||
t == cmake::DEPRECATION_ERROR) {
warningsAsErrors = this->GetDeprecatedWarningsAsErrors();
if (warningsAsErrors && t == cmake::DEPRECATION_WARNING) {
t = cmake::DEPRECATION_ERROR;
} else if (!warningsAsErrors && t == cmake::DEPRECATION_ERROR) {
t = cmake::DEPRECATION_WARNING;
}
}
return t;
}
bool cmMessenger::IsMessageTypeVisible(cmake::MessageType t) const
{
bool isVisible = true;
if (t == cmake::DEPRECATION_ERROR) {
if (!this->GetDeprecatedWarningsAsErrors()) {
isVisible = false;
}
} else if (t == cmake::DEPRECATION_WARNING) {
if (this->GetSuppressDeprecatedWarnings()) {
isVisible = false;
}
} else if (t == cmake::AUTHOR_ERROR) {
if (!this->GetDevWarningsAsErrors()) {
isVisible = false;
}
} else if (t == cmake::AUTHOR_WARNING) {
if (this->GetSuppressDevWarnings()) {
isVisible = false;
}
}
return isVisible;
}
static bool printMessagePreamble(cmake::MessageType t, std::ostream& msg)
{
// Construct the message header.
if (t == cmake::FATAL_ERROR) {
msg << "CMake Error";
} else if (t == cmake::INTERNAL_ERROR) {
msg << "CMake Internal Error (please report a bug)";
} else if (t == cmake::LOG) {
msg << "CMake Debug Log";
} else if (t == cmake::DEPRECATION_ERROR) {
msg << "CMake Deprecation Error";
} else if (t == cmake::DEPRECATION_WARNING) {
msg << "CMake Deprecation Warning";
} else if (t == cmake::AUTHOR_WARNING) {
msg << "CMake Warning (dev)";
} else if (t == cmake::AUTHOR_ERROR) {
msg << "CMake Error (dev)";
} else {
msg << "CMake Warning";
}
return true;
}
void printMessageText(std::ostream& msg, std::string const& text)
{
msg << ":\n";
cmDocumentationFormatter formatter;
formatter.SetIndent(" ");
formatter.PrintFormatted(msg, text.c_str());
}
void displayMessage(cmake::MessageType t, std::ostringstream& msg)
{
// Add a note about warning suppression.
if (t == cmake::AUTHOR_WARNING) {
msg << "This warning is for project developers. Use -Wno-dev to suppress "
"it.";
} else if (t == cmake::AUTHOR_ERROR) {
msg << "This error is for project developers. Use -Wno-error=dev to "
"suppress "
"it.";
}
// Add a terminating blank line.
msg << "\n";
#if defined(CMAKE_BUILD_WITH_CMAKE)
// Add a C++ stack trace to internal errors.
if (t == cmake::INTERNAL_ERROR) {
std::string stack = cmsys::SystemInformation::GetProgramStack(0, 0);
if (!stack.empty()) {
if (cmHasLiteralPrefix(stack, "WARNING:")) {
stack = "Note:" + stack.substr(8);
}
msg << stack << "\n";
}
}
#endif
// Output the message.
if (t == cmake::FATAL_ERROR || t == cmake::INTERNAL_ERROR ||
t == cmake::DEPRECATION_ERROR || t == cmake::AUTHOR_ERROR) {
cmSystemTools::SetErrorOccured();
cmSystemTools::Message(msg.str().c_str(), "Error");
} else {
cmSystemTools::Message(msg.str().c_str(), "Warning");
}
}
cmMessenger::cmMessenger(cmState* state)
: State(state)
{
}
void cmMessenger::IssueMessage(cmake::MessageType t, const std::string& text,
const cmListFileBacktrace& backtrace) const
{
bool force = false;
if (!force) {
// override the message type, if needed, for warnings and errors
cmake::MessageType override = this->ConvertMessageType(t);
if (override != t) {
t = override;
force = true;
}
}
if (!force && !this->IsMessageTypeVisible(t)) {
return;
}
this->DisplayMessage(t, text, backtrace);
}
void cmMessenger::DisplayMessage(cmake::MessageType t, const std::string& text,
const cmListFileBacktrace& backtrace) const
{
std::ostringstream msg;
if (!printMessagePreamble(t, msg)) {
return;
}
// Add the immediate context.
backtrace.PrintTitle(msg);
printMessageText(msg, text);
// Add the rest of the context.
backtrace.PrintCallStack(msg);
displayMessage(t, msg);
}
bool cmMessenger::GetSuppressDevWarnings() const
{
const char* cacheEntryValue =
this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
return cmSystemTools::IsOn(cacheEntryValue);
}
bool cmMessenger::GetSuppressDeprecatedWarnings() const
{
const char* cacheEntryValue =
this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
return cacheEntryValue && cmSystemTools::IsOff(cacheEntryValue);
}
bool cmMessenger::GetDevWarningsAsErrors() const
{
const char* cacheEntryValue =
this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_ERRORS");
return cacheEntryValue && cmSystemTools::IsOff(cacheEntryValue);
}
bool cmMessenger::GetDeprecatedWarningsAsErrors() const
{
const char* cacheEntryValue =
this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
return cmSystemTools::IsOn(cacheEntryValue);
}