[cmake-developers] Add command line options for deprecation message control

Michael Scott michael.scott250 at gmail.com
Sun Nov 1 11:09:02 EST 2015


> The semantic challenges are in the warning=>error conversion so I'd like
> to get the other parts reviewed and integrated first.
I've attached a version of the patch without the conversion 
functionality, for dev messages only, as the deprecated section wasn't 
part of this patch. I've also not included rst files in the commit, as 
it seems like a waste of time to revert them now and then change them 
back to what they should be afterwards. In the find commit the rst files 
will of course be in there.

One noticeable difference in this patch is the addition of an optional 
parameter to cmake::IssueMessage. This is intended to solve the future 
issue that the message command must support the setting the 
warning/error CMake variables in the CMake file itself, by changing the 
message type, whereas cmake::IssueMessage will only be checking the 
cache for the variables.

If there are any issues with this first chunk please let me know.

Cheers,
Michael
-------------- next part --------------
From 14ab5c6e0c46fc60ed9007fa06ce9b3c135e3150 Mon Sep 17 00:00:00 2001
From: Michael Scott <michael.scott250 at gmail.com>
Date: Sun, 1 Nov 2015 16:05:15 +0000
Subject: [PATCH] Add -W options to control deprecation and author warnings

Refactor the -Wdev and -Wno-dev options parser to use a generic -W
parser that follows the GCC pattern, excluding support for
-Werror=TYPE and -Wno-error=TYPE formats for now.

Add 'deprecated' warning options type, to allow setting
CMAKE_WARN_DEPRECATED via the -W options.

Add tests for new options.
---
 Source/cmMakefile.cxx                             |   8 +-
 Source/cmMakefile.h                               |   3 +-
 Source/cmMessageCommand.cxx                       |  12 +-
 Source/cmake.cxx                                  | 329 +++++++++++++++++++---
 Source/cmake.h                                    |  34 ++-
 Tests/RunCMake/CommandLine/RunCMakeTest.cmake     |  37 ++-
 Tests/RunCMake/CommandLine/W_bad-arg1-result.txt  |   1 +
 Tests/RunCMake/CommandLine/W_bad-arg1-stderr.txt  |   2 +
 Tests/RunCMake/CommandLine/W_bad-arg2-result.txt  |   1 +
 Tests/RunCMake/CommandLine/W_bad-arg2-stderr.txt  |   2 +
 Tests/RunCMake/CommandLine/Wdeprecated-stderr.txt |   4 +
 Tests/RunCMake/CommandLine/Wdeprecated.cmake      |   1 +
 Tests/RunCMake/CommandLine/Wdev-stderr.txt        |   2 +-
 Tests/RunCMake/CommandLine/Wdev.cmake             |   2 +-
 Tests/RunCMake/CommandLine/Wno-deprecated.cmake   |   1 +
 Tests/RunCMake/CommandLine/Wno-dev.cmake          |   2 +-
 Tests/RunCMake/message/RunCMakeTest.cmake         |   1 +
 Tests/RunCMake/message/defaultmessage-result.txt  |   1 +
 Tests/RunCMake/message/defaultmessage-stderr.txt  |  11 +
 Tests/RunCMake/message/defaultmessage.cmake       |   4 +
 Tests/RunCMake/message/nomessage.cmake            |  13 +
 21 files changed, 407 insertions(+), 64 deletions(-)
 create mode 100644 Tests/RunCMake/CommandLine/W_bad-arg1-result.txt
 create mode 100644 Tests/RunCMake/CommandLine/W_bad-arg1-stderr.txt
 create mode 100644 Tests/RunCMake/CommandLine/W_bad-arg2-result.txt
 create mode 100644 Tests/RunCMake/CommandLine/W_bad-arg2-stderr.txt
 create mode 100644 Tests/RunCMake/CommandLine/Wdeprecated-stderr.txt
 create mode 100644 Tests/RunCMake/CommandLine/Wdeprecated.cmake
 create mode 100644 Tests/RunCMake/CommandLine/Wno-deprecated.cmake
 create mode 100644 Tests/RunCMake/message/defaultmessage-result.txt
 create mode 100644 Tests/RunCMake/message/defaultmessage-stderr.txt
 create mode 100644 Tests/RunCMake/message/defaultmessage.cmake

diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index a1f143a..0eeb6ca 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -130,7 +130,8 @@ cmMakefile::~cmMakefile()
 
 //----------------------------------------------------------------------------
 void cmMakefile::IssueMessage(cmake::MessageType t,
-                              std::string const& text) const
+                              std::string const& text,
+                              bool ignoreWarningLevels) const
 {
   // Collect context information.
   if(!this->ExecutionStatusStack.empty())
@@ -139,7 +140,8 @@ void cmMakefile::IssueMessage(cmake::MessageType t,
       {
       this->ExecutionStatusStack.back()->SetNestedError(true);
       }
-    this->GetCMakeInstance()->IssueMessage(t, text, this->GetBacktrace());
+    this->GetCMakeInstance()->IssueMessage(t, text, this->GetBacktrace(),
+        ignoreWarningLevels);
     }
   else
     {
@@ -154,7 +156,7 @@ void cmMakefile::IssueMessage(cmake::MessageType t,
       lfc.FilePath = converter.Convert(lfc.FilePath, cmOutputConverter::HOME);
       }
     lfc.Line = 0;
-    this->GetCMakeInstance()->IssueMessage(t, text, lfc);
+    this->GetCMakeInstance()->IssueMessage(t, text, lfc, ignoreWarningLevels);
     }
 }
 
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 4215b72..878c13d 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -719,7 +719,8 @@ public:
   };
 
   void IssueMessage(cmake::MessageType t,
-                    std::string const& text) const;
+                    std::string const& text,
+                    bool ignoreWarningLevels = false) const;
 
   /** Set whether or not to report a CMP0000 violation.  */
   void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 2854a82..1c65ef7 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -43,7 +43,14 @@ bool cmMessageCommand
     }
   else if (*i == "AUTHOR_WARNING")
     {
-    type = cmake::AUTHOR_WARNING;
+    if (this->Makefile->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS"))
+      {
+      return true;
+      }
+    else
+      {
+      type = cmake::AUTHOR_WARNING;
+      }
     ++i;
     }
   else if (*i == "STATUS")
@@ -73,7 +80,8 @@ bool cmMessageCommand
 
   if (type != cmake::MESSAGE)
     {
-    this->Makefile->IssueMessage(type, message);
+    // we've overriden the message type, above, so force IssueMessage to use it
+    this->Makefile->IssueMessage(type, message, true);
     }
   else
     {
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 7268241..64f56f8 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -127,8 +127,6 @@ cmake::cmake()
   this->WarnUnused = false;
   this->WarnUnusedCli = true;
   this->CheckSystemVars = false;
-  this->SuppressDevWarnings = false;
-  this->DoSuppressDevWarnings = false;
   this->DebugOutput = false;
   this->DebugTryCompile = false;
   this->ClearBuildSystem = false;
@@ -250,15 +248,70 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
         return false;
         }
       }
-    else if(arg.find("-Wno-dev",0) == 0)
+    else if(cmHasLiteralPrefix(arg, "-W"))
       {
-      this->SuppressDevWarnings = true;
-      this->DoSuppressDevWarnings = true;
+      std::string entry = arg.substr(2);
+      if (entry.empty())
+        {
+        ++i;
+        if (i < args.size())
+          {
+          entry = args[i];
+          }
+        else
+          {
+          cmSystemTools::Error(
+            "-W must be followed with [no-][error=]<name>.");
+          return false;
+        }
       }
-    else if(arg.find("-Wdev",0) == 0)
-      {
-      this->SuppressDevWarnings = false;
-      this->DoSuppressDevWarnings = true;
+
+      std::string name;
+      bool foundNo = false;
+      bool foundError = false;
+      unsigned int nameStartPosition = 0;
+
+      if (entry.find("no-", nameStartPosition) == 0)
+        {
+        foundNo = true;
+        nameStartPosition += 3;
+        }
+
+      if (entry.find("error=", nameStartPosition) == 0)
+        {
+        foundError = true;
+        nameStartPosition += 6;
+        }
+
+      name = entry.substr(nameStartPosition);
+      if (name.empty())
+        {
+        cmSystemTools::Error("No warning name provided.");
+        return false;
+        }
+
+      if (!foundNo && !foundError)
+        {
+        // -W<name>
+        this->WarningLevels[name] = std::max(this->WarningLevels[name],
+                                             WARNING_LEVEL);
+        }
+      else if (foundNo && !foundError)
+        {
+         // -Wno<name>
+         this->WarningLevels[name] = IGNORE_LEVEL;
+        }
+      else if (!foundNo && foundError)
+        {
+        // -Werror=<name>
+        this->WarningLevels[name] = ERROR_LEVEL;
+        }
+      else
+        {
+        // -Wno-error=<name>
+        this->WarningLevels[name] = std::min(this->WarningLevels[name],
+                                             WARNING_LEVEL);
+        }
       }
     else if(arg.find("-U",0) == 0)
       {
@@ -591,11 +644,7 @@ void cmake::SetArgs(const std::vector<std::string>& args,
       // skip for now
       i++;
       }
-    else if(arg.find("-Wno-dev",0) == 0)
-      {
-      // skip for now
-      }
-    else if(arg.find("-Wdev",0) == 0)
+    else if(arg.find("-W",0) == 0)
       {
       // skip for now
       }
@@ -1190,25 +1239,133 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
 
 int cmake::Configure()
 {
-  if(this->DoSuppressDevWarnings)
+  WarningLevel warningLevel;
+
+  if (this->WarningLevels.count("deprecated") == 1)
     {
-    if(this->SuppressDevWarnings)
+    warningLevel = this->WarningLevels["deprecated"];
+    if (warningLevel == IGNORE_LEVEL)
       {
-      this->
-        AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "TRUE",
-                      "Suppress Warnings that are meant for"
-                      " the author of the CMakeLists.txt files.",
-                      cmState::INTERNAL);
+      this->AddCacheEntry("CMAKE_WARN_DEPRECATED", "FALSE",
+                          "Whether to issue deprecation warnings for"
+                          " macros and functions.",
+                          cmState::BOOL);
+      this->AddCacheEntry("CMAKE_ERROR_DEPRECATED", "FALSE",
+                          "Whether to issue deprecation errors for macros"
+                          " and functions.",
+                          cmState::BOOL);
       }
-    else
+    if (warningLevel == WARNING_LEVEL)
+      {
+      this->AddCacheEntry("CMAKE_WARN_DEPRECATED", "TRUE",
+                          "Whether to issue deprecation warnings for"
+                          " macros and functions.",
+                          cmState::BOOL);
+      this->AddCacheEntry("CMAKE_ERROR_DEPRECATED", "FALSE",
+                          "Whether to issue deprecation errors for macros"
+                          " and functions.",
+                          cmState::BOOL);
+      }
+    else if (warningLevel == ERROR_LEVEL)
+      {
+      this->AddCacheEntry("CMAKE_WARN_DEPRECATED", "FALSE",
+                          "Whether to issue deprecation warnings for"
+                          " macros and functions.",
+                          cmState::BOOL);
+      this->AddCacheEntry("CMAKE_ERROR_DEPRECATED", "TRUE",
+                          "Whether to issue deprecation errors for macros"
+                          " and functions.",
+                          cmState::BOOL);
+      }
+    }
+
+  if (this->WarningLevels.count("dev") == 1)
+    {
+    bool setDeprecatedVariables = false;
+
+    const char* cachedWarnDeprecated =
+           this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
+    const char* cachedErrorDeprecated =
+           this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
+
+    // don't overwrite deprecated warning setting from a previous invocation
+    if (!cachedWarnDeprecated && !cachedErrorDeprecated)
+      {
+      setDeprecatedVariables = true;
+      }
+
+    warningLevel = this->WarningLevels["dev"];
+    if (warningLevel == IGNORE_LEVEL)
+      {
+      this->AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "TRUE",
+                          "Suppress Warnings that are meant for"
+                          " the author of the CMakeLists.txt files.",
+                          cmState::INTERNAL);
+      this->AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_ERRORS", "TRUE",
+                          "Suppress errors that are meant for"
+                          " the author of the CMakeLists.txt files.",
+                          cmState::INTERNAL);
+
+      if (setDeprecatedVariables)
+        {
+        this->AddCacheEntry("CMAKE_WARN_DEPRECATED", "FALSE",
+                            "Whether to issue deprecation warnings for"
+                            " macros and functions.",
+                            cmState::BOOL);
+        this->AddCacheEntry("CMAKE_ERROR_DEPRECATED", "FALSE",
+                            "Whether to issue deprecation errors for macros"
+                            " and functions.",
+                            cmState::BOOL);
+        }
+      }
+    else if (warningLevel == WARNING_LEVEL)
+      {
+      this->AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "FALSE",
+                          "Suppress Warnings that are meant for"
+                          " the author of the CMakeLists.txt files.",
+                          cmState::INTERNAL);
+      this->AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_ERRORS", "TRUE",
+                          "Suppress errors that are meant for"
+                          " the author of the CMakeLists.txt files.",
+                          cmState::INTERNAL);
+
+      if (setDeprecatedVariables)
+        {
+        this->AddCacheEntry("CMAKE_WARN_DEPRECATED", "TRUE",
+                            "Whether to issue deprecation warnings for"
+                            " macros and functions.",
+                            cmState::BOOL);
+        this->AddCacheEntry("CMAKE_ERROR_DEPRECATED", "FALSE",
+                            "Whether to issue deprecation errors for macros"
+                            " and functions.",
+                            cmState::BOOL);
+        }
+      }
+    else if (warningLevel == ERROR_LEVEL)
       {
-      this->
-        AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "FALSE",
-                      "Suppress Warnings that are meant for"
-                      " the author of the CMakeLists.txt files.",
-                      cmState::INTERNAL);
+      this->AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "FALSE",
+                          "Suppress Warnings that are meant for"
+                          " the author of the CMakeLists.txt files.",
+                          cmState::INTERNAL);
+      this->AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_ERRORS", "FALSE",
+                          "Suppress errors that are meant for"
+                          " the author of the CMakeLists.txt files.",
+                          cmState::INTERNAL);
+
+      if (setDeprecatedVariables)
+        {
+        this->AddCacheEntry("CMAKE_WARN_DEPRECATED", "FALSE",
+                            "Whether to issue deprecation warnings for"
+                            " macros and functions.",
+                            cmState::BOOL);
+        this->AddCacheEntry("CMAKE_ERROR_DEPRECATED", "TRUE",
+                            "Whether to issue deprecation errors for macros"
+                            " and functions.",
+                            cmState::BOOL);
+        }
       }
     }
+
   int ret = this->ActualConfigure();
   const char* delCacheVars = this->State
                     ->GetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_");
@@ -1539,6 +1696,10 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
     {
     this->AddCMakePaths();
     }
+
+  // turn on author, and in turn deprecated, warnings (only) by default
+  this->WarningLevels["dev"] = WARNING_LEVEL;
+
   // Add any cache args
   if ( !this->SetCacheArgs(args) )
     {
@@ -2444,6 +2605,56 @@ static bool cmakeCheckStampList(const char* stampList)
   return true;
 }
 
+bool cmake::IsMessageTypeVisible(cmake::MessageType t)
+{
+  bool isVisible = true;
+
+  if(t == cmake::DEPRECATION_ERROR)
+    {
+    // if CMAKE_ERROR_DEPRECATED is on, show the message, otherwise suppress it
+    const char* errorDeprecated = this->State->GetCacheEntryValue(
+                                                "CMAKE_ERROR_DEPRECATED");
+    if(cmSystemTools::IsOff(errorDeprecated))
+      {
+      isVisible = false;
+      }
+    }
+  else if (t == cmake::DEPRECATION_WARNING)
+    {
+    // if CMAKE_WARN_DEPRECATED is on, show the message, otherwise suppress it
+    const char* warnDeprecated = this->State->GetInitializedCacheValue(
+                                            "CMAKE_WARN_DEPRECATED");
+    if(cmSystemTools::IsOff(warnDeprecated))
+      {
+      isVisible = false;
+      }
+    }
+  else if (t == cmake::AUTHOR_WARNING)
+    {
+    // if CMAKE_SUPPRESS_DEVELOPER_WARNINGS is on, suppress the message,
+    // otherwise show it
+    const char* suppressDevWarnings = this->State->GetCacheEntryValue(
+                                          "CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
+    if(cmSystemTools::IsOn(suppressDevWarnings))
+      {
+      isVisible = false;
+      }
+    }
+  else if (t == cmake::AUTHOR_ERROR)
+    {
+    // if CMAKE_SUPPRESS_DEVELOPER_WARNINGS is on, suppress the message,
+    // otherwise show it
+    const char* suppressDevErrors = this->State->GetCacheEntryValue(
+                                          "CMAKE_SUPPRESS_DEVELOPER_ERRORS");
+    if(cmSystemTools::IsOn(suppressDevErrors))
+      {
+      isVisible = false;
+      }
+    }
+
+  return isVisible;
+}
+
 bool cmake::PrintMessagePreamble(cmake::MessageType t, std::ostream& msg)
 {
   // Construct the message header.
@@ -2467,20 +2678,17 @@ bool cmake::PrintMessagePreamble(cmake::MessageType t, std::ostream& msg)
     {
     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";
-    if(t == cmake::AUTHOR_WARNING)
-      {
-      // Allow suppression of these warnings.
-      const char* suppress = this->State->GetCacheEntryValue(
-                                        "CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
-      if(suppress && cmSystemTools::IsOn(suppress))
-        {
-        return false;
-        }
-      msg << " (dev)";
-      }
     }
   return true;
 }
@@ -2502,6 +2710,12 @@ void displayMessage(cmake::MessageType t, std::ostringstream& msg)
     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";
@@ -2525,7 +2739,8 @@ void displayMessage(cmake::MessageType t, std::ostringstream& msg)
   // Output the message.
   if(t == cmake::FATAL_ERROR
      || t == cmake::INTERNAL_ERROR
-     || t == cmake::DEPRECATION_ERROR)
+     || t == cmake::DEPRECATION_ERROR
+     || t == cmake::AUTHOR_ERROR)
     {
     cmSystemTools::SetErrorOccured();
     cmSystemTools::Message(msg.str().c_str(), "Error");
@@ -2538,10 +2753,16 @@ void displayMessage(cmake::MessageType t, std::ostringstream& msg)
 
 //----------------------------------------------------------------------------
 void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
-                         cmListFileBacktrace const& bt)
+                         cmListFileBacktrace const& bt,
+                         bool ignoreWarningLevels)
 {
   cmListFileBacktrace backtrace = bt;
 
+  if (!ignoreWarningLevels && !this->IsMessageTypeVisible(t))
+    {
+    return;
+    }
+
   std::ostringstream msg;
   if (!this->PrintMessagePreamble(t, msg))
     {
@@ -2557,12 +2778,23 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
   backtrace.PrintCallStack(msg);
 
   displayMessage(t, msg);
+
+  if (t == cmake::DEPRECATION_ERROR || t == cmake::AUTHOR_ERROR)
+    {
+    cmSystemTools::SetFatalErrorOccured();
+    }
 }
 
 //----------------------------------------------------------------------------
 void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
-                         cmListFileContext const& lfc)
+                         cmListFileContext const& lfc,
+                         bool ignoreWarningLevels)
 {
+  if (!ignoreWarningLevels && !this->IsMessageTypeVisible(t))
+    {
+    return;
+    }
+
   std::ostringstream msg;
   if (!this->PrintMessagePreamble(t, msg))
     {
@@ -2722,3 +2954,18 @@ void cmake::RunCheckForUnusedVariables()
     }
 #endif
 }
+
+void cmake::SetSuppressDevWarnings(bool b)
+{
+  // equivalent to -Wno-dev
+  if (b)
+    {
+    this->WarningLevels["dev"] = IGNORE_LEVEL;
+    }
+  // equivalent to -Wdev
+  else
+    {
+    this->WarningLevels["dev"] = std::max(this->WarningLevels["dev"],
+                                          WARNING_LEVEL);
+    }
+}
diff --git a/Source/cmake.h b/Source/cmake.h
index 9d28cba..c5a2cac 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -59,6 +59,7 @@ class cmake
  public:
   enum MessageType
   { AUTHOR_WARNING,
+    AUTHOR_ERROR,
     FATAL_ERROR,
     INTERNAL_ERROR,
     MESSAGE,
@@ -68,6 +69,12 @@ class cmake
     DEPRECATION_WARNING
   };
 
+  enum WarningLevel
+  {
+    IGNORE_LEVEL,
+    WARNING_LEVEL,
+    ERROR_LEVEL
+  };
 
   /** \brief Describes the working modes of cmake */
   enum WorkingMode
@@ -271,6 +278,7 @@ class cmake
   void SetTrace(bool b) {  this->Trace = b;}
   bool GetTraceExpand() { return this->TraceExpand;}
   void SetTraceExpand(bool b) {  this->TraceExpand = b;}
+  void SetSuppressDevWarnings(bool b);
   bool GetWarnUninitialized() { return this->WarnUninitialized;}
   void SetWarnUninitialized(bool b) {  this->WarnUninitialized = b;}
   bool GetWarnUnused() { return this->WarnUnused;}
@@ -291,17 +299,13 @@ class cmake
   std::string const& GetCMakeEditCommand() const
     { return this->CMakeEditCommand; }
 
-  void SetSuppressDevWarnings(bool v)
-    {
-      this->SuppressDevWarnings = v;
-      this->DoSuppressDevWarnings = true;
-    }
-
   /** Display a message to the user.  */
   void IssueMessage(cmake::MessageType t, std::string const& text,
-        cmListFileBacktrace const& backtrace = cmListFileBacktrace());
+        cmListFileBacktrace const& backtrace = cmListFileBacktrace(),
+        bool ignoreWarningLevels = false);
   void IssueMessage(cmake::MessageType t, std::string const& text,
-        cmListFileContext const& lfc);
+        cmListFileContext const& lfc,
+        bool ignoreWarningLevels = false);
 
   ///! run the --build option
   int Build(const std::string& dir,
@@ -339,8 +343,7 @@ protected:
 
   cmGlobalGenerator *GlobalGenerator;
   cmCacheManager *CacheManager;
-  bool SuppressDevWarnings;
-  bool DoSuppressDevWarnings;
+  std::map<std::string, WarningLevel> WarningLevels;
   std::string GeneratorPlatform;
   std::string GeneratorToolset;
 
@@ -406,6 +409,13 @@ private:
   void PrintGeneratorList();
 
   bool PrintMessagePreamble(cmake::MessageType t, std::ostream& msg);
+
+  /*
+   * Check if messages of this type should be output, based on the state of the
+   * warning and error output CMake variables, in the cache.
+   */
+
+  bool IsMessageTypeVisible(cmake::MessageType t);
 };
 
 #define CMAKE_STANDARD_OPTIONS_TABLE \
@@ -416,7 +426,9 @@ private:
   {"-T <toolset-name>", "Specify toolset name if supported by generator."}, \
   {"-A <platform-name>", "Specify platform name if supported by generator."}, \
   {"-Wno-dev", "Suppress developer warnings."},\
-  {"-Wdev", "Enable developer warnings."}
+  {"-Wdev", "Enable developer warnings."},\
+  {"-Wdeprecated", "Enable deprecated macro and function warnings."},\
+  {"-Wno-deprecated", "Suppress deprecated macro and function warnings."}
 
 #define FOR_EACH_C_FEATURE(F) \
   F(c_function_prototypes) \
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index 2d94e29..e09ff28 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -125,14 +125,45 @@ set(RunCMake_TEST_OPTIONS
   "-DFOO:STRING=-DBAR:BOOL=BAZ")
 run_cmake(D_typed_nested_cache)
 
-set(RunCMake_TEST_OPTIONS -Wno-dev)
-run_cmake(Wno-dev)
+set(RunCMake_TEST_OPTIONS -Wdev)
+run_cmake(Wdev)
+unset(RunCMake_TEST_OPTIONS)
+
+# -Wdev should not override deprecated options if specified
+set(RunCMake_TEST_OPTIONS -Wdev -Wno-deprecated)
+run_cmake(Wno-deprecated)
+unset(RunCMake_TEST_OPTIONS)
+set(RunCMake_TEST_OPTIONS -Wno-deprecated -Wdev)
+run_cmake(Wno-deprecated)
+unset(RunCMake_TEST_OPTIONS)
+
+# -Wdev should enable deprecated warnings as well
+set(RunCMake_TEST_OPTIONS -Wdev)
+run_cmake(Wdeprecated)
 unset(RunCMake_TEST_OPTIONS)
 
-set(RunCMake_TEST_OPTIONS -Wno-dev -Wdev)
+set(RunCMake_TEST_OPTIONS -Wdeprecated)
+run_cmake(Wdeprecated)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS -Wno-deprecated)
+run_cmake(Wno-deprecated)
+unset(RunCMake_TEST_OPTIONS)
+
+# Dev warnings should be on by default
 run_cmake(Wdev)
+
+# Deprecated warnings should be on by default
+run_cmake(Wdeprecated)
+
+# Conflicting -W options should honor the last value
+set(RunCMake_TEST_OPTIONS -Wdev -Wno-dev)
+run_cmake(Wno-dev)
 unset(RunCMake_TEST_OPTIONS)
 
+run_cmake_command(W_bad-arg1 ${CMAKE_COMMAND} -W)
+run_cmake_command(W_bad-arg2 ${CMAKE_COMMAND} -Wno-)
+
 set(RunCMake_TEST_OPTIONS --debug-output)
 run_cmake(debug-output)
 unset(RunCMake_TEST_OPTIONS)
diff --git a/Tests/RunCMake/CommandLine/W_bad-arg1-result.txt b/Tests/RunCMake/CommandLine/W_bad-arg1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/W_bad-arg1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/W_bad-arg1-stderr.txt b/Tests/RunCMake/CommandLine/W_bad-arg1-stderr.txt
new file mode 100644
index 0000000..e912728
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/W_bad-arg1-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error: -W must be followed with \[no-\]\[error=\]<name>.
+CMake Error: Problem processing arguments. Aborting.
diff --git a/Tests/RunCMake/CommandLine/W_bad-arg2-result.txt b/Tests/RunCMake/CommandLine/W_bad-arg2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/W_bad-arg2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/W_bad-arg2-stderr.txt b/Tests/RunCMake/CommandLine/W_bad-arg2-stderr.txt
new file mode 100644
index 0000000..cc643df
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/W_bad-arg2-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error: No warning name provided.
+CMake Error: Problem processing arguments. Aborting.
diff --git a/Tests/RunCMake/CommandLine/Wdeprecated-stderr.txt b/Tests/RunCMake/CommandLine/Wdeprecated-stderr.txt
new file mode 100644
index 0000000..e9be1dc
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wdeprecated-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Deprecation Warning at Wdeprecated.cmake:1 \(message\):
+  Some deprecated warning
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CommandLine/Wdeprecated.cmake b/Tests/RunCMake/CommandLine/Wdeprecated.cmake
new file mode 100644
index 0000000..3142b42
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wdeprecated.cmake
@@ -0,0 +1 @@
+message(DEPRECATION "Some deprecated warning")
diff --git a/Tests/RunCMake/CommandLine/Wdev-stderr.txt b/Tests/RunCMake/CommandLine/Wdev-stderr.txt
index 92c1d23..88cfb3a 100644
--- a/Tests/RunCMake/CommandLine/Wdev-stderr.txt
+++ b/Tests/RunCMake/CommandLine/Wdev-stderr.txt
@@ -1,5 +1,5 @@
 ^CMake Warning \(dev\) at Wdev.cmake:1 \(message\):
-  Some Author Warning
+  Some author warning
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
 This warning is for project developers.  Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CommandLine/Wdev.cmake b/Tests/RunCMake/CommandLine/Wdev.cmake
index e5026ef..756f31e 100644
--- a/Tests/RunCMake/CommandLine/Wdev.cmake
+++ b/Tests/RunCMake/CommandLine/Wdev.cmake
@@ -1,4 +1,4 @@
-message(AUTHOR_WARNING "Some Author Warning")
+message(AUTHOR_WARNING "Some author warning")
 
 # with -Wdev this will also cause an AUTHOR_WARNING message, checks that
 # messages issued outside of the message command, by other CMake commands, also
diff --git a/Tests/RunCMake/CommandLine/Wno-deprecated.cmake b/Tests/RunCMake/CommandLine/Wno-deprecated.cmake
new file mode 100644
index 0000000..3142b42
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wno-deprecated.cmake
@@ -0,0 +1 @@
+message(DEPRECATION "Some deprecated warning")
diff --git a/Tests/RunCMake/CommandLine/Wno-dev.cmake b/Tests/RunCMake/CommandLine/Wno-dev.cmake
index d81b858..802b435 100644
--- a/Tests/RunCMake/CommandLine/Wno-dev.cmake
+++ b/Tests/RunCMake/CommandLine/Wno-dev.cmake
@@ -1,4 +1,4 @@
-message(AUTHOR_WARNING "Some Author Warning")
+message(AUTHOR_WARNING "Some author warning")
 
 # without -Wno-dev this will also cause an AUTHOR_WARNING message, checks that
 # messages issued outside of the message command, by other CMake commands, also
diff --git a/Tests/RunCMake/message/RunCMakeTest.cmake b/Tests/RunCMake/message/RunCMakeTest.cmake
index d2bc0c3..294dfbb 100644
--- a/Tests/RunCMake/message/RunCMakeTest.cmake
+++ b/Tests/RunCMake/message/RunCMakeTest.cmake
@@ -1,5 +1,6 @@
 include(RunCMake)
 
+run_cmake(defaultmessage)
 run_cmake(nomessage)
 run_cmake(warnmessage)
 run_cmake(errormessage)
diff --git a/Tests/RunCMake/message/defaultmessage-result.txt b/Tests/RunCMake/message/defaultmessage-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/message/defaultmessage-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/message/defaultmessage-stderr.txt b/Tests/RunCMake/message/defaultmessage-stderr.txt
new file mode 100644
index 0000000..e7bd3fa
--- /dev/null
+++ b/Tests/RunCMake/message/defaultmessage-stderr.txt
@@ -0,0 +1,11 @@
+CMake Deprecation Warning at defaultmessage.cmake:2 \(message\):
+  This is issued by default
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+
+
+CMake Warning \(dev\) at defaultmessage.cmake:4 \(message\):
+  This is also issued by default
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
\ No newline at end of file
diff --git a/Tests/RunCMake/message/defaultmessage.cmake b/Tests/RunCMake/message/defaultmessage.cmake
new file mode 100644
index 0000000..d9f14f9
--- /dev/null
+++ b/Tests/RunCMake/message/defaultmessage.cmake
@@ -0,0 +1,4 @@
+# deprecation and author messages are issued by default now
+message(DEPRECATION "This is issued by default")
+
+message(AUTHOR_WARNING "This is also issued by default")
diff --git a/Tests/RunCMake/message/nomessage.cmake b/Tests/RunCMake/message/nomessage.cmake
index bcc97be..558a560 100644
--- a/Tests/RunCMake/message/nomessage.cmake
+++ b/Tests/RunCMake/message/nomessage.cmake
@@ -1,2 +1,15 @@
+set(CMAKE_WARN_DEPRECATED OFF)
 
 message(DEPRECATION "This is not issued")
+
+set(CMAKE_ERROR_DEPRECATED OFF)
+
+message(DEPRECATION "This is not issued")
+
+set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS ON)
+
+message(AUTHOR_WARNING "This is not issued")
+
+set(CMAKE_SUPPRESS_DEVELOPER_ERRORS ON)
+
+message(AUTHOR_WARNING "This is not issued")
\ No newline at end of file
-- 
2.1.4



More information about the cmake-developers mailing list