cmMessenger: Extract from cmake class

This way messages can be issued independent of the cmake instance.

It is now possible to make DisplayMessage a virtual interface and
override it to handle messages in the cmake-gui or future IDE
interaction interfaces.
This commit is contained in:
Stephen Kelly 2016-01-28 22:10:27 +01:00 committed by Brad King
parent 14a8d61fd4
commit 421012a330
7 changed files with 277 additions and 168 deletions

View File

@ -319,6 +319,8 @@ set(SRCS
cmMakefileExecutableTargetGenerator.cxx
cmMakefileLibraryTargetGenerator.cxx
cmMakefileUtilityTargetGenerator.cxx
cmMessenger.cxx
cmMessenger.h
cmOSXBundleGenerator.cxx
cmOSXBundleGenerator.h
cmOutputConverter.cxx

View File

@ -11,6 +11,8 @@
============================================================================*/
#include "cmMessageCommand.h"
#include "cmMessenger.h"
// cmLibraryCommand
bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&)
@ -65,8 +67,8 @@ bool cmMessageCommand::InitialPass(std::vector<std::string> const& args,
if (type != cmake::MESSAGE) {
// we've overriden the message type, above, so display it directly
cmake* cm = this->Makefile->GetCMakeInstance();
cm->DisplayMessage(type, message, this->Makefile->GetBacktrace());
cmMessenger* m = this->Makefile->GetMessenger();
m->DisplayMessage(type, message, this->Makefile->GetBacktrace());
} else {
if (status) {
this->Makefile->DisplayStatus(message.c_str(), -1);

209
Source/cmMessenger.cxx Normal file
View File

@ -0,0 +1,209 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#include "cmMessenger.h"
#include "cmDocumentationFormatter.h"
#include "cmMessenger.h"
#include "cmOutputConverter.h"
#if defined(CMAKE_BUILD_WITH_CMAKE)
#include <cmsys/SystemInformation.hxx>
#endif
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);
}

44
Source/cmMessenger.h Normal file
View File

@ -0,0 +1,44 @@
/*============================================================================
CMake - Cross Platform Makefile Generator
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#ifndef cmMessenger_h
#define cmMessenger_h
#include "cmListFileCache.h"
#include "cmState.h"
#include "cmake.h"
class cmMessenger
{
public:
cmMessenger(cmState* state);
void IssueMessage(
cmake::MessageType t, std::string const& text,
cmListFileBacktrace const& backtrace = cmListFileBacktrace()) const;
void DisplayMessage(cmake::MessageType t, std::string const& text,
cmListFileBacktrace const& backtrace) const;
bool GetSuppressDevWarnings() const;
bool GetSuppressDeprecatedWarnings() const;
bool GetDevWarningsAsErrors() const;
bool GetDeprecatedWarningsAsErrors() const;
private:
bool IsMessageTypeVisible(cmake::MessageType t) const;
cmake::MessageType ConvertMessageType(cmake::MessageType t) const;
cmState* State;
};
#endif

View File

@ -19,6 +19,7 @@
#include "cmFileTimeComparison.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessenger.h"
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmTest.h"
@ -152,6 +153,7 @@ cmake::cmake()
this->State = new cmState;
this->CurrentSnapshot = this->State->CreateBaseSnapshot();
this->Messenger = new cmMessenger(this->State);
#ifdef __APPLE__
struct rlimit rlp;
@ -207,6 +209,7 @@ cmake::cmake()
cmake::~cmake()
{
delete this->State;
delete this->Messenger;
if (this->GlobalGenerator) {
delete this->GlobalGenerator;
this->GlobalGenerator = CM_NULLPTR;
@ -2281,160 +2284,10 @@ static bool cmakeCheckStampList(const char* stampList)
return true;
}
cmake::MessageType cmake::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 cmake::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");
}
}
void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
cmListFileBacktrace const& backtrace) const
{
bool force = false;
// 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 cmake::DisplayMessage(cmake::MessageType t, std::string const& text,
cmListFileBacktrace const& 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);
this->Messenger->IssueMessage(t, text, backtrace);
}
std::vector<std::string> cmake::GetDebugConfigs()
@ -2454,6 +2307,11 @@ std::vector<std::string> cmake::GetDebugConfigs()
return configs;
}
cmMessenger* cmake::GetMessenger() const
{
return this->Messenger;
}
int cmake::Build(const std::string& dir, const std::string& target,
const std::string& config,
const std::vector<std::string>& nativeOptions, bool clean)
@ -2560,9 +2418,7 @@ void cmake::RunCheckForUnusedVariables()
bool cmake::GetSuppressDevWarnings() const
{
const char* cacheEntryValue =
this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
return cmSystemTools::IsOn(cacheEntryValue);
return this->Messenger->GetSuppressDevWarnings();
}
void cmake::SetSuppressDevWarnings(bool b)
@ -2586,9 +2442,7 @@ void cmake::SetSuppressDevWarnings(bool b)
bool cmake::GetSuppressDeprecatedWarnings() const
{
const char* cacheEntryValue =
this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
return cacheEntryValue && cmSystemTools::IsOff(cacheEntryValue);
return this->Messenger->GetSuppressDeprecatedWarnings();
}
void cmake::SetSuppressDeprecatedWarnings(bool b)
@ -2612,9 +2466,7 @@ void cmake::SetSuppressDeprecatedWarnings(bool b)
bool cmake::GetDevWarningsAsErrors() const
{
const char* cacheEntryValue =
this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_ERRORS");
return cacheEntryValue && cmSystemTools::IsOff(cacheEntryValue);
return this->Messenger->GetDevWarningsAsErrors();
}
void cmake::SetDevWarningsAsErrors(bool b)
@ -2638,9 +2490,7 @@ void cmake::SetDevWarningsAsErrors(bool b)
bool cmake::GetDeprecatedWarningsAsErrors() const
{
const char* cacheEntryValue =
this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
return cmSystemTools::IsOn(cacheEntryValue);
return this->Messenger->GetDeprecatedWarningsAsErrors();
}
void cmake::SetDeprecatedWarningsAsErrors(bool b)

View File

@ -25,6 +25,7 @@ class cmGlobalGeneratorFactory;
class cmGlobalGenerator;
class cmLocalGenerator;
class cmMakefile;
class cmMessenger;
class cmVariableWatch;
class cmFileTimeComparison;
class cmExternalMakefileProjectGeneratorFactory;
@ -346,6 +347,8 @@ public:
return this->CMakeEditCommand;
}
cmMessenger* GetMessenger() const;
/*
* Get the state of the suppression of developer (author) warnings.
* Returns false, by default, if developer warnings should be shown, true
@ -395,9 +398,6 @@ public:
cmake::MessageType t, std::string const& text,
cmListFileBacktrace const& backtrace = cmListFileBacktrace()) const;
void DisplayMessage(cmake::MessageType t, std::string const& text,
cmListFileBacktrace const& backtrace) const;
///! run the --build option
int Build(const std::string& dir, const std::string& target,
const std::string& config,
@ -491,6 +491,7 @@ private:
cmState* State;
cmState::Snapshot CurrentSnapshot;
cmMessenger* Messenger;
std::vector<std::string> TraceOnlyThisSources;

View File

@ -266,6 +266,7 @@ CMAKE_CXX_SOURCES="\
cmPropertyDefinition \
cmPropertyDefinitionMap \
cmMakefile \
cmMessenger \
cmExportBuildFileGenerator \
cmExportFileGenerator \
cmExportInstallFileGenerator \