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

Michael Scott michael.scott250 at gmail.com
Mon Jul 27 19:07:03 EDT 2015


Hi,

After the last feedback, I've made some changes which should address the 
points that were talked about.

I've changed the -W dev options to affect the deprecated warnings/errors 
as well, but only if the user hasn't used one of the options that 
control deprecated warnings (-Wdeprecated, -Wno-deprecated, 
-Werror=deprecated, -Wno-error=deprecated), if they have then the -W dev 
options won't affect the CMAKE_WARN_DEPRECATED or CMAKE_ERROR_DEPRECATED 
variables.

I've also added the two -W dev options, "-Werror=dev" and 
"-Wno-error=dev", to bring this set of options in line with the 
deprecated set of options. For this I've added a new variable, 
CMAKE_SUPPRESS_DEVELOPER_ERRORS, which controls whether or not author 
warnings are treated as fatal errors. By default it's set to TRUE as 
this seemed more sensible.

I've added some more cases to the run CMake tests and updated the 
documentation to contain the new options and variable, I've also added a 
document to the dev release notes in case these additional changes 
merited one.

Please let me know if there are any mistakes/issues with the attached 
commit or if I've missed out anything.

I've started some changes to the QT GUI to allow it to use these 
changes, but I thought it'd be best to commit the given changes now, and 
then do a separate chunk of work for the QT GUI changes, as the changes 
for all this have grown larger than expected.

Cheers,
Michael Scott
-------------- next part --------------
From 3ed09142ec81861670ca2fe27e28ca782ad60e9f Mon Sep 17 00:00:00 2001
From: Michael Scott <michael.scott250 at gmail.com>
Date: Sat, 13 Jun 2015 18:34:31 +0100
Subject: [PATCH] Refactored the -Wdev and -Wno-dev to use a generic -W parser,
 which follows the GCC pattern. Included support for setting
 CMAKE_ERROR_DEPRECATED and CMAKE_WARN_DEPRECATED via the deprecated warning.
 Added -Werror=dev and -Wno-error=dev options, so that dev warning options are
 in line with deprecated warning options. Added a new variable
 CMAKE_SUPPRESS_DEVELOPER_ERRORS, which is set using the above new dev
 options. Added tests for new options and updated cmake documentation and
 release notes to list new options.

---
 Help/manual/OPTIONS_BUILD.txt                      |  40 +++-
 Help/manual/cmake-variables.7.rst                  |   2 +
 Help/release/dev/cmake-Wdeprecated.rst             |   9 +
 Help/release/dev/cmake-Wdev.rst                    |   7 +
 Help/variable/CMAKE_ERROR_DEPRECATED.rst           |   4 +
 Help/variable/CMAKE_SUPPRESS_DEVELOPER_ERRORS.rst  |  12 ++
 Help/variable/CMAKE_WARN_DEPRECATED.rst            |   4 +
 Source/cmMessageCommand.cxx                        |  14 +-
 Source/cmake.cxx                                   | 239 ++++++++++++++++++---
 Source/cmake.h                                     |  27 ++-
 Tests/RunCMake/CommandLine/RunCMakeTest.cmake      |  63 ++++++
 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/W_bad-arg3-result.txt   |   1 +
 Tests/RunCMake/CommandLine/W_bad-arg3-stderr.txt   |   2 +
 Tests/RunCMake/CommandLine/Wdeprecated-stderr.txt  |   4 +
 Tests/RunCMake/CommandLine/Wdeprecated.cmake       |   1 +
 .../CommandLine/Werror_deprecated-result.txt       |   1 +
 .../CommandLine/Werror_deprecated-stderr.txt       |   4 +
 Tests/RunCMake/CommandLine/Werror_deprecated.cmake |   1 +
 Tests/RunCMake/CommandLine/Werror_dev-result.txt   |   1 +
 Tests/RunCMake/CommandLine/Werror_dev-stderr.txt   |   5 +
 Tests/RunCMake/CommandLine/Werror_dev.cmake        |   1 +
 Tests/RunCMake/CommandLine/Wno-deprecated.cmake    |   1 +
 .../CommandLine/Wno-error_deprecated.cmake         |   1 +
 Tests/RunCMake/CommandLine/Wno-error_dev.cmake     |   1 +
 28 files changed, 408 insertions(+), 43 deletions(-)
 create mode 100644 Help/release/dev/cmake-Wdeprecated.rst
 create mode 100644 Help/release/dev/cmake-Wdev.rst
 create mode 100644 Help/variable/CMAKE_SUPPRESS_DEVELOPER_ERRORS.rst
 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/W_bad-arg3-result.txt
 create mode 100644 Tests/RunCMake/CommandLine/W_bad-arg3-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/Werror_deprecated-result.txt
 create mode 100644 Tests/RunCMake/CommandLine/Werror_deprecated-stderr.txt
 create mode 100644 Tests/RunCMake/CommandLine/Werror_deprecated.cmake
 create mode 100644 Tests/RunCMake/CommandLine/Werror_dev-result.txt
 create mode 100644 Tests/RunCMake/CommandLine/Werror_dev-stderr.txt
 create mode 100644 Tests/RunCMake/CommandLine/Werror_dev.cmake
 create mode 100644 Tests/RunCMake/CommandLine/Wno-deprecated.cmake
 create mode 100644 Tests/RunCMake/CommandLine/Wno-error_deprecated.cmake
 create mode 100644 Tests/RunCMake/CommandLine/Wno-error_dev.cmake

diff --git a/Help/manual/OPTIONS_BUILD.txt b/Help/manual/OPTIONS_BUILD.txt
index 4207db4..34e890f 100644
--- a/Help/manual/OPTIONS_BUILD.txt
+++ b/Help/manual/OPTIONS_BUILD.txt
@@ -77,10 +77,46 @@
  Suppress developer warnings.
 
  Suppress warnings that are meant for the author of the
- CMakeLists.txt files.
+ CMakeLists.txt files. By default this will also turn off deprecated warnings.
 
 ``-Wdev``
  Enable developer warnings.
 
  Enable warnings that are meant for the author of the CMakeLists.txt
- files.
+ files. By default this will also turn on deprecated warnings.
+
+``-Werror=dev``
+ Make developer warnings errors.
+
+ Make warnings that are meant for the author of the CMakeLists.txt files
+ errors. By default this will also turn on deprecated warnings as errors.
+
+``-Wno-error=dev``
+ Make developer warnings not errors.
+
+ Make warnings that are meant for the author of the CMakeLists.txt files not
+ errors. By default this will also turn off deprecated warnings as errors.
+
+``-Wdeprecated``
+ Enable deprecated macro and function warnings.
+
+ Enable warnings for usage of deprecated macros and functions, that are meant 
+ for the author of the CMakeLists.txt files. 
+
+``-Wno-deprecated``
+ Suppress deprecated macro and function warnings.
+ 
+ Suppress warnings for usage of deprecated macros and functions, that are meant 
+ for the author of the CMakeLists.txt files. 
+
+``-Werror=deprecated``
+ Make deprecated macro and function warnings errors.
+
+ Make warnings for usage of deprecated macros and functions, that are meant 
+ for the author of the CMakeLists.txt files, errors. 
+
+``-Wno-error=deprecated``
+ Make deprecated macro and function warnings not errors.
+ 
+ Make warnings for usage of deprecated macros and functions, that are meant 
+ for the author of the CMakeLists.txt files, not errors.
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index f010d28..3e4c39b 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -149,6 +149,7 @@ Variables that Change Behavior
    /variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE
    /variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY
    /variable/CMAKE_STAGING_PREFIX
+   /variable/CMAKE_SUPPRESS_DEVELOPER_ERRORS
    /variable/CMAKE_SYSTEM_APPBUNDLE_PATH
    /variable/CMAKE_SYSTEM_FRAMEWORK_PATH
    /variable/CMAKE_SYSTEM_IGNORE_PATH
@@ -239,6 +240,7 @@ Variables that Control the Build
    /variable/CMAKE_INSTALL_NAME_DIR
    /variable/CMAKE_INSTALL_RPATH
    /variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH
+   /variable/CMAKE_LANG_COMPILER_LAUNCHER
    /variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE
    /variable/CMAKE_LANG_VISIBILITY_PRESET
    /variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY
diff --git a/Help/release/dev/cmake-Wdeprecated.rst b/Help/release/dev/cmake-Wdeprecated.rst
new file mode 100644
index 0000000..7b89fc3
--- /dev/null
+++ b/Help/release/dev/cmake-Wdeprecated.rst
@@ -0,0 +1,9 @@
+cmake-Wdeprecated
+-----------------
+
+The :variable:`CMAKE_ERROR_DEPRECATED` variable can now be set using the
+``-Werror=deprecated`` and ``-Wno-error=deprecated`` :manual:`cmake(1)`
+options.
+
+The :variable:`CMAKE_WARN_DEPRECATED` variable can now be set using the
+``-Wdeprecated`` and ``-Wno-deprecated`` :manual:`cmake(1)` options.
diff --git a/Help/release/dev/cmake-Wdev.rst b/Help/release/dev/cmake-Wdev.rst
new file mode 100644
index 0000000..9daf057
--- /dev/null
+++ b/Help/release/dev/cmake-Wdev.rst
@@ -0,0 +1,7 @@
+cmake-Wdev
+----------
+
+CMake learned the new :variable:`CMAKE_SUPPRESS_DEVELOPER_ERRORS` variable
+to supress developer errors intended for CMake authors. This variable is
+TRUE by default and can now be set using the ``-Werror=dev`` and
+``-Wno-error=dev`` :manual:`cmake(1)` options.
diff --git a/Help/variable/CMAKE_ERROR_DEPRECATED.rst b/Help/variable/CMAKE_ERROR_DEPRECATED.rst
index 43ab282..68befc2 100644
--- a/Help/variable/CMAKE_ERROR_DEPRECATED.rst
+++ b/Help/variable/CMAKE_ERROR_DEPRECATED.rst
@@ -6,3 +6,7 @@ Whether to issue deprecation errors for macros and functions.
 If TRUE, this can be used by macros and functions to issue fatal
 errors when deprecated macros or functions are used.  This variable is
 FALSE by default.
+
+These errors can be enabled with the ``-Werror=deprecated`` option, or
+disabled with the ``-Wno-error=deprecated`` option, when running
+:manual:`cmake(1)`.
diff --git a/Help/variable/CMAKE_SUPPRESS_DEVELOPER_ERRORS.rst b/Help/variable/CMAKE_SUPPRESS_DEVELOPER_ERRORS.rst
new file mode 100644
index 0000000..34a8087
--- /dev/null
+++ b/Help/variable/CMAKE_SUPPRESS_DEVELOPER_ERRORS.rst
@@ -0,0 +1,12 @@
+CMAKE_SUPPRESS_DEVELOPER_ERRORS
+-------------------------------
+
+Whether to supress developer errors intended for authors of CMakeLists.txt
+files.
+
+If TRUE, developer warnings issued by macros and functions will not be
+treated as fatal erors. This variable is TRUE by default. Setting this
+variable will not affect the suppression of developer warnings.
+
+These errors can be enabled with the ``-Werror=dev`` option, or disabled
+with the ``-Wno-error=dev`` option, when running :manual:`cmake(1)`.
diff --git a/Help/variable/CMAKE_WARN_DEPRECATED.rst b/Help/variable/CMAKE_WARN_DEPRECATED.rst
index 7b2510b..2a13895 100644
--- a/Help/variable/CMAKE_WARN_DEPRECATED.rst
+++ b/Help/variable/CMAKE_WARN_DEPRECATED.rst
@@ -5,3 +5,7 @@ Whether to issue deprecation warnings for macros and functions.
 
 If TRUE, this can be used by macros and functions to issue deprecation
 warnings.  This variable is FALSE by default.
+
+These warnings can be enabled with the ``-Wdeprecated`` option, or
+disabled with the ``-Wno-deprecated`` option, when running
+:manual:`cmake(1)`.
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 0449c50..219a70c 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -43,7 +43,19 @@ bool cmMessageCommand
     }
   else if (*i == "AUTHOR_WARNING")
     {
-    type = cmake::AUTHOR_WARNING;
+    if (!this->Makefile->IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS"))
+      {
+      fatal = true;
+      type = cmake::AUTHOR_ERROR;
+      }
+    else if (!this->Makefile->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS"))
+      {
+      type = cmake::AUTHOR_WARNING;
+      }
+    else
+      {
+      return true;
+      }
     ++i;
     }
   else if (*i == "STATUS")
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index eeb6575..2905db0 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -125,8 +125,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;
@@ -186,7 +184,7 @@ cmake::~cmake()
 
 void cmake::CleanupCommandsAndMacros()
 {
-  this->State->Reset();
+  this->CurrentSnapshot = this->State->Reset();
   this->State->RemoveUserDefinedCommands();
 }
 
@@ -251,15 +249,69 @@ 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)
       {
@@ -370,6 +422,7 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
   // read in the list file to fill the cache
   if(path)
     {
+    this->CurrentSnapshot = this->State->Reset();
     std::string homeDir = this->GetHomeDirectory();
     std::string homeOutputDir = this->GetHomeOutputDirectory();
     this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
@@ -482,7 +535,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
     std::string linkPath;
     std::string flags;
     std::string linkFlags;
-    gg->CreateGeneratorTargets(mf);
+    gg->CreateGeneratorTargets(lg.get());
     cmGeneratorTarget *gtgt = gg->GetGeneratorTarget(tgt);
     lg->GetTargetFlags(linkLibs, frameworkPath, linkPath, flags, linkFlags,
                        gtgt, false);
@@ -587,11 +640,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
       }
@@ -1171,25 +1220,121 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
 
 int cmake::Configure()
 {
-  if(this->DoSuppressDevWarnings)
+  WarningLevel warningLevel;
+
+  if (this->WarningLevels.count("deprecated") == 1)
+    {
+    warningLevel = this->WarningLevels["deprecated"];
+    if (warningLevel == IGNORE_LEVEL)
+      {
+      this->CacheManager->
+        AddCacheEntry("CMAKE_WARN_DEPRECATED", "FALSE",
+                      "Whether to issue deprecation warnings for"
+                      " macros and functions.",
+                      cmState::BOOL);
+      this->CacheManager->
+        AddCacheEntry("CMAKE_ERROR_DEPRECATED", "FALSE",
+                      "Whether to issue deprecation errors for macros"
+                      " and functions.",
+                      cmState::BOOL);
+      }
+    if (warningLevel == WARNING_LEVEL)
+      {
+      this->CacheManager->
+        AddCacheEntry("CMAKE_WARN_DEPRECATED", "TRUE",
+                      "Whether to issue deprecation warnings for"
+                      " macros and functions.",
+                      cmState::BOOL);
+      }
+    else if (warningLevel == ERROR_LEVEL)
+      {
+      this->CacheManager->
+        AddCacheEntry("CMAKE_ERROR_DEPRECATED", "TRUE",
+                      "Whether to issue deprecation errors for macros"
+                      " and functions.",
+                      cmState::BOOL);
+      }
+    }
+
+  if (this->WarningLevels.count("dev") == 1)
     {
-    if(this->SuppressDevWarnings)
+    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->CacheManager->
         AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "TRUE",
                       "Suppress Warnings that are meant for"
                       " the author of the CMakeLists.txt files.",
                       cmState::INTERNAL);
+      this->CacheManager->
+        AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_ERRORS", "TRUE",
+                      "Suppress errors that are meant for"
+                      " the author of the CMakeLists.txt files.",
+                      cmState::INTERNAL);
+
+      if (setDeprecatedVariables)
+        {
+        this->CacheManager->
+          AddCacheEntry("CMAKE_WARN_DEPRECATED", "FALSE",
+                        "Whether to issue deprecation warnings for"
+                        " macros and functions.",
+                        cmState::BOOL);
+        this->CacheManager->
+          AddCacheEntry("CMAKE_ERROR_DEPRECATED", "FALSE",
+                        "Whether to issue deprecation errors for macros"
+                        " and functions.",
+                        cmState::BOOL);
+        }
       }
-    else
+    else if (warningLevel == WARNING_LEVEL)
       {
       this->CacheManager->
         AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "FALSE",
                       "Suppress Warnings that are meant for"
                       " the author of the CMakeLists.txt files.",
                       cmState::INTERNAL);
+
+      if (setDeprecatedVariables)
+        {
+        this->CacheManager->
+          AddCacheEntry("CMAKE_WARN_DEPRECATED", "TRUE",
+                        "Whether to issue deprecation warnings for"
+                        " macros and functions.",
+                        cmState::BOOL);
+        }
+      }
+    else if (warningLevel == ERROR_LEVEL)
+      {
+      this->CacheManager->
+        AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_ERRORS", "FALSE",
+                      "Suppress errors that are meant for"
+                      " the author of the CMakeLists.txt files.",
+                      cmState::INTERNAL);
+
+      if (setDeprecatedVariables)
+        {
+        this->CacheManager->
+          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_");
@@ -1533,6 +1678,18 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
     {
     this->AddCMakePaths();
     }
+
+  // don't turn dev warnings into errors by default, if no value has been
+  // specified for the flag, enable it
+  if (!this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_ERRORS"))
+    {
+    this->CacheManager->
+            AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_ERRORS", "TRUE",
+                          "Suppress errors that are meant for"
+                          " the author of the CMakeLists.txt files.",
+                          cmState::INTERNAL);
+    }
+
   // Add any cache args
   if ( !this->SetCacheArgs(args) )
     {
@@ -2431,20 +2588,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;
 }
@@ -2466,6 +2620,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";
@@ -2489,7 +2649,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");
@@ -2667,3 +2828,19 @@ 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 f0f9411..7b679d3 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -60,6 +60,7 @@ class cmake
  public:
   enum MessageType
   { AUTHOR_WARNING,
+    AUTHOR_ERROR,
     FATAL_ERROR,
     INTERNAL_ERROR,
     MESSAGE,
@@ -69,6 +70,12 @@ class cmake
     DEPRECATION_WARNING
   };
 
+  enum WarningLevel
+  {
+    IGNORE_LEVEL,
+    WARNING_LEVEL,
+    ERROR_LEVEL
+  };
 
   /** \brief Describes the working modes of cmake */
   enum WorkingMode
@@ -270,6 +277,7 @@ class cmake
   // Do we want trace output during the cmake run.
   bool GetTrace() { return this->Trace;}
   void SetTrace(bool b) {  this->Trace = b;}
+  void SetSuppressDevWarnings(bool b);
   bool GetWarnUninitialized() { return this->WarnUninitialized;}
   void SetWarnUninitialized(bool b) {  this->WarnUninitialized = b;}
   bool GetWarnUnused() { return this->WarnUnused;}
@@ -290,12 +298,6 @@ 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());
@@ -339,8 +341,7 @@ protected:
   cmPolicies *Policies;
   cmGlobalGenerator *GlobalGenerator;
   cmCacheManager *CacheManager;
-  bool SuppressDevWarnings;
-  bool DoSuppressDevWarnings;
+  std::map<std::string, WarningLevel> WarningLevels;
   std::string GeneratorPlatform;
   std::string GeneratorToolset;
 
@@ -415,7 +416,15 @@ 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."},\
+  {"-Werror=dev", "Make developer warnings errors."},\
+  {"-Wno-error=dev", "Make developer warnings not errors."},\
+  {"-Wdeprecated", "Enable deprecated macro and function warnings."},\
+  {"-Wno-deprecated", "Suppress deprecated macro and function warnings."},\
+  {"-Werror=deprecated", "Make deprecated macro and function warnings " \
+                         "errors."},\
+  {"-Wno-error=deprecated", "Make deprecated macro and function warnings " \
+                            "not errors."}
 
 #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 69beed9..40b560c 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -22,13 +22,30 @@ run_cmake_command(G_bad-arg ${CMAKE_COMMAND} -G NoSuchGenerator)
 run_cmake_command(P_no-arg ${CMAKE_COMMAND} -P)
 run_cmake_command(P_no-file ${CMAKE_COMMAND} -P nosuchscriptfile.cmake)
 
+run_cmake_command(build-no-dir
+  ${CMAKE_COMMAND} --build)
 run_cmake_command(build-no-cache
   ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR})
 run_cmake_command(build-no-generator
   ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-no-generator)
+run_cmake_command(build-bad-dir
+  ${CMAKE_COMMAND} --build dir-does-not-exist)
 run_cmake_command(build-bad-generator
   ${CMAKE_COMMAND} --build ${RunCMake_SOURCE_DIR}/cache-bad-generator)
 
+function(run_BuildDir)
+  # Use a single build tree for a few tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/BuildDir-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  run_cmake(BuildDir)
+  run_cmake_command(BuildDir--build ${CMAKE_COMMAND} -E chdir ..
+    ${CMAKE_COMMAND} --build BuildDir-build --target CustomTarget)
+endfunction()
+run_BuildDir()
+
 if(RunCMake_GENERATOR STREQUAL "Ninja")
   # Use a single build tree for a few tests without cleaning.
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Build-build)
@@ -115,6 +132,52 @@ set(RunCMake_TEST_OPTIONS -Wno-dev -Wdev)
 run_cmake(Wdev)
 unset(RunCMake_TEST_OPTIONS)
 
+set(RunCMake_TEST_OPTIONS -Werror=dev)
+run_cmake(Werror_dev)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS -Wno-error=dev)
+run_cmake(Wno-error_deprecated)
+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)
+
+# -Werror=dev should enable deprecated errors as well
+set(RunCMake_TEST_OPTIONS -Werror=dev)
+run_cmake(Werror_deprecated)
+unset(RunCMake_TEST_OPTIONS)
+
+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)
+
+set(RunCMake_TEST_OPTIONS -Werror=deprecated)
+run_cmake(Werror_deprecated)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS -Wno-error=deprecated)
+run_cmake(Wno-error_deprecated)
+unset(RunCMake_TEST_OPTIONS)
+
+run_cmake_command(W_bad-arg1 ${CMAKE_COMMAND} -W)
+run_cmake_command(W_bad-arg2 ${CMAKE_COMMAND} -Wno-)
+run_cmake_command(W_bad-arg3 ${CMAKE_COMMAND} -Werror=)
+
 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/W_bad-arg3-result.txt b/Tests/RunCMake/CommandLine/W_bad-arg3-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/W_bad-arg3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/W_bad-arg3-stderr.txt b/Tests/RunCMake/CommandLine/W_bad-arg3-stderr.txt
new file mode 100644
index 0000000..cc643df
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/W_bad-arg3-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/Werror_deprecated-result.txt b/Tests/RunCMake/CommandLine/Werror_deprecated-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Werror_deprecated-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/Werror_deprecated-stderr.txt b/Tests/RunCMake/CommandLine/Werror_deprecated-stderr.txt
new file mode 100644
index 0000000..6acdc73
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Werror_deprecated-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Deprecation Error at Werror_deprecated.cmake:1 \(message\):
+  Some deprecated warning
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CommandLine/Werror_deprecated.cmake b/Tests/RunCMake/CommandLine/Werror_deprecated.cmake
new file mode 100644
index 0000000..3142b42
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Werror_deprecated.cmake
@@ -0,0 +1 @@
+message(DEPRECATION "Some deprecated warning")
diff --git a/Tests/RunCMake/CommandLine/Werror_dev-result.txt b/Tests/RunCMake/CommandLine/Werror_dev-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Werror_dev-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/Werror_dev-stderr.txt b/Tests/RunCMake/CommandLine/Werror_dev-stderr.txt
new file mode 100644
index 0000000..c6b4e74
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Werror_dev-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error \(dev\) at Werror_dev.cmake:1 \(message\):
+  Some author warning
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This error is for project developers. Use -Wno-error=dev to suppress it.$
diff --git a/Tests/RunCMake/CommandLine/Werror_dev.cmake b/Tests/RunCMake/CommandLine/Werror_dev.cmake
new file mode 100644
index 0000000..e05cf9d
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Werror_dev.cmake
@@ -0,0 +1 @@
+message(AUTHOR_WARNING "Some author warning")
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-error_deprecated.cmake b/Tests/RunCMake/CommandLine/Wno-error_deprecated.cmake
new file mode 100644
index 0000000..3142b42
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wno-error_deprecated.cmake
@@ -0,0 +1 @@
+message(DEPRECATION "Some deprecated warning")
diff --git a/Tests/RunCMake/CommandLine/Wno-error_dev.cmake b/Tests/RunCMake/CommandLine/Wno-error_dev.cmake
new file mode 100644
index 0000000..e05cf9d
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/Wno-error_dev.cmake
@@ -0,0 +1 @@
+message(AUTHOR_WARNING "Some author warning")
-- 
2.1.4



More information about the cmake-developers mailing list