瀏覽代碼

Merge topic 'cmake-W-options'

82166701 cmake-gui: Add options to control warning-as-error messages
28f2d750 Add -Werror and -Wno-error command-line options
Brad King 9 年之前
父節點
當前提交
59dac28856
共有 32 個文件被更改,包括 532 次插入37 次删除
  1. 24 0
      Help/manual/OPTIONS_BUILD.txt
  2. 7 0
      Help/release/dev/cmake-W-options.rst
  3. 20 0
      Source/QtDialog/QCMake.cxx
  4. 8 0
      Source/QtDialog/QCMake.h
  5. 56 0
      Source/QtDialog/WarningMessagesDialog.cxx
  6. 22 0
      Source/QtDialog/WarningMessagesDialog.h
  7. 55 2
      Source/QtDialog/WarningMessagesDialog.ui
  8. 15 14
      Source/cmMessageCommand.cxx
  9. 191 9
      Source/cmake.cxx
  10. 39 3
      Source/cmake.h
  11. 22 0
      Tests/RunCMake/CommandLine/RunCMakeTest.cmake
  12. 0 0
      Tests/RunCMake/CommandLine/W_bad-arg3-result.txt
  13. 2 0
      Tests/RunCMake/CommandLine/W_bad-arg3-stderr.txt
  14. 1 0
      Tests/RunCMake/CommandLine/Werror_deprecated-result.txt
  15. 4 0
      Tests/RunCMake/CommandLine/Werror_deprecated-stderr.txt
  16. 1 0
      Tests/RunCMake/CommandLine/Werror_deprecated.cmake
  17. 1 0
      Tests/RunCMake/CommandLine/Werror_dev-result.txt
  18. 11 0
      Tests/RunCMake/CommandLine/Werror_dev-stderr.txt
  19. 7 0
      Tests/RunCMake/CommandLine/Werror_dev.cmake
  20. 4 0
      Tests/RunCMake/CommandLine/Wno-error_deprecated-stderr.txt
  21. 2 0
      Tests/RunCMake/CommandLine/Wno-error_deprecated.cmake
  22. 11 0
      Tests/RunCMake/CommandLine/Wno-error_dev-stderr.txt
  23. 7 0
      Tests/RunCMake/CommandLine/Wno-error_dev.cmake
  24. 5 1
      Tests/RunCMake/message/RunCMakeTest.cmake
  25. 0 4
      Tests/RunCMake/message/errormessage-stderr.txt
  26. 0 4
      Tests/RunCMake/message/errormessage.cmake
  27. 1 0
      Tests/RunCMake/message/errormessage_deprecated-result.txt
  28. 4 0
      Tests/RunCMake/message/errormessage_deprecated-stderr.txt
  29. 3 0
      Tests/RunCMake/message/errormessage_deprecated.cmake
  30. 1 0
      Tests/RunCMake/message/errormessage_dev-result.txt
  31. 5 0
      Tests/RunCMake/message/errormessage_dev-stderr.txt
  32. 3 0
      Tests/RunCMake/message/errormessage_dev.cmake

+ 24 - 0
Help/manual/OPTIONS_BUILD.txt

@@ -86,6 +86,18 @@
  Enable warnings that are meant for the author of the CMakeLists.txt
  Enable warnings that are meant for the author of the CMakeLists.txt
  files. By default this will also turn on deprecation warnings.
  files. By default this will also turn on deprecation 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``
 ``-Wdeprecated``
  Enable deprecated functionality warnings.
  Enable deprecated functionality warnings.
 
 
@@ -97,3 +109,15 @@
 
 
  Suppress warnings for usage of deprecated functionality, that are meant
  Suppress warnings for usage of deprecated functionality, that are meant
  for the author of the CMakeLists.txt files.
  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.

+ 7 - 0
Help/release/dev/cmake-W-options.rst

@@ -13,3 +13,10 @@ cmake-W-options
 
 
 * Warnings about deprecated functionality can now be controlled in the
 * Warnings about deprecated functionality can now be controlled in the
   :manual:`cmake-gui(1)` application.
   :manual:`cmake-gui(1)` application.
+
+* The suppression of developer warnings as errors can now be controlled with
+  the new ``-Werror=dev`` and ``-Wno-error=dev`` :manual:`cmake(1)` options.
+
+* The :variable:`CMAKE_ERROR_DEPRECATED` variable can now be set using the
+  ``-Werror=deprecated`` and ``-Wno-error=deprecated`` :manual:`cmake(1)`
+  options.

+ 20 - 0
Source/QtDialog/QCMake.cxx

@@ -475,6 +475,26 @@ void QCMake::setSuppressDeprecatedWarnings(bool value)
   this->CMakeInstance->SetSuppressDeprecatedWarnings(value);
   this->CMakeInstance->SetSuppressDeprecatedWarnings(value);
 }
 }
 
 
+bool QCMake::getDevWarningsAsErrors()
+{
+  return this->CMakeInstance->GetDevWarningsAsErrors();
+}
+
+void QCMake::setDevWarningsAsErrors(bool value)
+{
+  this->CMakeInstance->SetDevWarningsAsErrors(value);
+}
+
+bool QCMake::getDeprecatedWarningsAsErrors()
+{
+  return this->CMakeInstance->GetDeprecatedWarningsAsErrors();
+}
+
+void QCMake::setDeprecatedWarningsAsErrors(bool value)
+{
+  this->CMakeInstance->SetDeprecatedWarningsAsErrors(value);
+}
+
 void QCMake::setWarnUninitializedMode(bool value)
 void QCMake::setWarnUninitializedMode(bool value)
 {
 {
   this->WarnUninitializedMode = value;
   this->WarnUninitializedMode = value;

+ 8 - 0
Source/QtDialog/QCMake.h

@@ -99,6 +99,14 @@ public slots:
   bool getSuppressDeprecatedWarnings();
   bool getSuppressDeprecatedWarnings();
   /// set whether to do suppress deprecated warnings
   /// set whether to do suppress deprecated warnings
   void setSuppressDeprecatedWarnings(bool value);
   void setSuppressDeprecatedWarnings(bool value);
+  /// get whether to treat developer (author) warnings as errors
+  bool getDevWarningsAsErrors();
+  /// set whether to treat developer (author) warnings as errors
+  void setDevWarningsAsErrors(bool value);
+  /// get whether to treat deprecated warnings as errors
+  bool getDeprecatedWarningsAsErrors();
+  /// set whether to treat deprecated warnings as errors
+  void setDeprecatedWarningsAsErrors(bool value);
   /// set whether to run cmake with warnings about uninitialized variables
   /// set whether to run cmake with warnings about uninitialized variables
   void setWarnUninitializedMode(bool value);
   void setWarnUninitializedMode(bool value);
   /// set whether to run cmake with warnings about unused variables
   /// set whether to run cmake with warnings about unused variables

+ 56 - 0
Source/QtDialog/WarningMessagesDialog.cxx

@@ -26,12 +26,27 @@ void WarningMessagesDialog::setInitialValues()
     this->cmakeInstance->getSuppressDevWarnings());
     this->cmakeInstance->getSuppressDevWarnings());
   this->suppressDeprecatedWarnings->setChecked(
   this->suppressDeprecatedWarnings->setChecked(
     this->cmakeInstance->getSuppressDeprecatedWarnings());
     this->cmakeInstance->getSuppressDeprecatedWarnings());
+
+  this->developerWarningsAsErrors->setChecked(
+    this->cmakeInstance->getDevWarningsAsErrors());
+  this->deprecatedWarningsAsErrors->setChecked(
+    this->cmakeInstance->getDeprecatedWarningsAsErrors());
 }
 }
 
 
 void WarningMessagesDialog::setupSignals()
 void WarningMessagesDialog::setupSignals()
 {
 {
   QObject::connect(this->buttonBox, SIGNAL(accepted()),
   QObject::connect(this->buttonBox, SIGNAL(accepted()),
                    this, SLOT(doAccept()));
                    this, SLOT(doAccept()));
+
+  QObject::connect(this->suppressDeveloperWarnings, SIGNAL(stateChanged(int)),
+                   this, SLOT(doSuppressDeveloperWarningsChanged(int)));
+  QObject::connect(this->suppressDeprecatedWarnings, SIGNAL(stateChanged(int)),
+                   this, SLOT(doSuppressDeprecatedWarningsChanged(int)));
+
+  QObject::connect(this->developerWarningsAsErrors, SIGNAL(stateChanged(int)),
+                   this, SLOT(doDeveloperWarningsAsErrorsChanged(int)));
+  QObject::connect(this->deprecatedWarningsAsErrors, SIGNAL(stateChanged(int)),
+                   this, SLOT(doDeprecatedWarningsAsErrorsChanged(int)));
 }
 }
 
 
 void WarningMessagesDialog::doAccept()
 void WarningMessagesDialog::doAccept()
@@ -40,4 +55,45 @@ void WarningMessagesDialog::doAccept()
     this->suppressDeveloperWarnings->isChecked());
     this->suppressDeveloperWarnings->isChecked());
   this->cmakeInstance->setSuppressDeprecatedWarnings(
   this->cmakeInstance->setSuppressDeprecatedWarnings(
     this->suppressDeprecatedWarnings->isChecked());
     this->suppressDeprecatedWarnings->isChecked());
+
+  this->cmakeInstance->setDevWarningsAsErrors(
+    this->developerWarningsAsErrors->isChecked());
+  this->cmakeInstance->setDeprecatedWarningsAsErrors(
+    this->deprecatedWarningsAsErrors->isChecked());
+}
+
+void WarningMessagesDialog::doSuppressDeveloperWarningsChanged(int state)
+{
+  // no warnings implies no errors either
+  if (state)
+    {
+    this->developerWarningsAsErrors->setChecked(false);
+    }
+}
+
+void WarningMessagesDialog::doSuppressDeprecatedWarningsChanged(int state)
+{
+  // no warnings implies no errors either
+  if (state)
+    {
+    this->deprecatedWarningsAsErrors->setChecked(false);
+    }
+}
+
+void WarningMessagesDialog::doDeveloperWarningsAsErrorsChanged(int state)
+{
+  // warnings as errors implies warnings are not suppressed
+  if (state)
+    {
+    this->suppressDeveloperWarnings->setChecked(false);
+    }
+}
+
+void WarningMessagesDialog::doDeprecatedWarningsAsErrorsChanged(int state)
+{
+  // warnings as errors implies warnings are not suppressed
+  if (state)
+    {
+    this->suppressDeprecatedWarnings->setChecked(false);
+    }
 }
 }

+ 22 - 0
Source/QtDialog/WarningMessagesDialog.h

@@ -35,6 +35,28 @@ private slots:
    */
    */
   void doAccept();
   void doAccept();
 
 
+  /**
+   * Handler for checked state changed event of the suppress developer warnings
+   * checkbox.
+   */
+  void doSuppressDeveloperWarningsChanged(int state);
+  /**
+   * Handler for checked state changed event of the suppress deprecated
+   * warnings checkbox.
+   */
+  void doSuppressDeprecatedWarningsChanged(int state);
+
+  /**
+   * Handler for checked state changed event of the developer warnings as
+   * errors checkbox.
+   */
+  void doDeveloperWarningsAsErrorsChanged(int state);
+  /**
+   * Handler for checked state changed event of the deprecated warnings as
+   * errors checkbox.
+   */
+  void doDeprecatedWarningsAsErrorsChanged(int state);
+
 private:
 private:
   QCMake* cmakeInstance;
   QCMake* cmakeInstance;
 
 

+ 55 - 2
Source/QtDialog/WarningMessagesDialog.ui

@@ -6,8 +6,8 @@
    <rect>
    <rect>
     <x>0</x>
     <x>0</x>
     <y>0</y>
     <y>0</y>
-    <width>250</width>
-    <height>150</height>
+    <width>300</width>
+    <height>300</height>
    </rect>
    </rect>
   </property>
   </property>
   <property name="windowTitle">
   <property name="windowTitle">
@@ -37,6 +37,9 @@
           <verstretch>0</verstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
          </sizepolicy>
         </property>
         </property>
+        <property name="toolTip">
+         <string>Suppress developer (author) warnings.</string>
+        </property>
         <property name="text">
         <property name="text">
          <string>Developer Warnings</string>
          <string>Developer Warnings</string>
         </property>
         </property>
@@ -53,6 +56,9 @@
           <verstretch>0</verstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
          </sizepolicy>
         </property>
         </property>
+        <property name="toolTip">
+         <string>Suppress deprecated warnings.</string>
+        </property>
         <property name="text">
         <property name="text">
          <string>Deprecated Warnings</string>
          <string>Deprecated Warnings</string>
         </property>
         </property>
@@ -64,6 +70,53 @@
      </layout>
      </layout>
     </widget>
     </widget>
    </item>
    </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox_2">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="title">
+      <string>Warnings as Errors</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_3">
+      <item>
+       <widget class="QCheckBox" name="developerWarningsAsErrors">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="toolTip">
+         <string>Treat developer (author) warnings as errors.</string>
+        </property>
+        <property name="text">
+         <string>Developer Warnings as Errors</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QCheckBox" name="deprecatedWarningsAsErrors">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="toolTip">
+         <string>Treat deprecated warnings as errors.</string>
+        </property>
+        <property name="text">
+         <string>Deprecated Warnings as Errors</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
    <item>
    <item>
     <widget class="QDialogButtonBox" name="buttonBox">
     <widget class="QDialogButtonBox" name="buttonBox">
      <property name="sizePolicy">
      <property name="sizePolicy">

+ 15 - 14
Source/cmMessageCommand.cxx

@@ -25,6 +25,7 @@ bool cmMessageCommand
   cmake::MessageType type = cmake::MESSAGE;
   cmake::MessageType type = cmake::MESSAGE;
   bool status = false;
   bool status = false;
   bool fatal = false;
   bool fatal = false;
+  cmake* cm = this->Makefile->GetCMakeInstance();
   if (*i == "SEND_ERROR")
   if (*i == "SEND_ERROR")
     {
     {
     type = cmake::FATAL_ERROR;
     type = cmake::FATAL_ERROR;
@@ -43,15 +44,19 @@ bool cmMessageCommand
     }
     }
   else if (*i == "AUTHOR_WARNING")
   else if (*i == "AUTHOR_WARNING")
     {
     {
-    if (this->Makefile->GetCMakeInstance()->GetSuppressDevWarnings(
-        this->Makefile))
+    if (cm->GetDevWarningsAsErrors(this->Makefile))
       {
       {
-      return true;
+      fatal = true;
+      type = cmake::AUTHOR_ERROR;
       }
       }
-    else
+    else if (!cm->GetSuppressDevWarnings(this->Makefile))
       {
       {
       type = cmake::AUTHOR_WARNING;
       type = cmake::AUTHOR_WARNING;
       }
       }
+    else
+      {
+      return true;
+      }
     ++i;
     ++i;
     }
     }
   else if (*i == "STATUS")
   else if (*i == "STATUS")
@@ -61,22 +66,18 @@ bool cmMessageCommand
     }
     }
   else if (*i == "DEPRECATION")
   else if (*i == "DEPRECATION")
     {
     {
-    if (this->Makefile->IsOn("CMAKE_ERROR_DEPRECATED"))
+    if (cm->GetDeprecatedWarningsAsErrors(this->Makefile))
       {
       {
       fatal = true;
       fatal = true;
       type = cmake::DEPRECATION_ERROR;
       type = cmake::DEPRECATION_ERROR;
       }
       }
+    else if (!cm->GetSuppressDeprecatedWarnings(this->Makefile))
+      {
+      type = cmake::DEPRECATION_WARNING;
+      }
     else
     else
       {
       {
-      if (this->Makefile->GetCMakeInstance()->GetSuppressDeprecatedWarnings(
-          this->Makefile))
-        {
-        return true;
-        }
-      else
-        {
-        type = cmake::DEPRECATION_WARNING;
-        }
+      return true;
       }
       }
     ++i;
     ++i;
     }
     }

+ 191 - 9
Source/cmake.cxx

@@ -291,6 +291,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
 
 
       std::string name;
       std::string name;
       bool foundNo = false;
       bool foundNo = false;
+      bool foundError = false;
       unsigned int nameStartPosition = 0;
       unsigned int nameStartPosition = 0;
 
 
       if (entry.find("no-", nameStartPosition) == 0)
       if (entry.find("no-", nameStartPosition) == 0)
@@ -299,6 +300,12 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
         nameStartPosition += 3;
         nameStartPosition += 3;
         }
         }
 
 
+      if (entry.find("error=", nameStartPosition) == 0)
+        {
+        foundError = true;
+        nameStartPosition += 6;
+        }
+
       name = entry.substr(nameStartPosition);
       name = entry.substr(nameStartPosition);
       if (name.empty())
       if (name.empty())
         {
         {
@@ -306,16 +313,27 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
         return false;
         return false;
         }
         }
 
 
-      if (!foundNo)
+      if (!foundNo && !foundError)
         {
         {
         // -W<name>
         // -W<name>
         this->DiagLevels[name] = std::max(this->DiagLevels[name],
         this->DiagLevels[name] = std::max(this->DiagLevels[name],
                                           DIAG_WARN);
                                           DIAG_WARN);
         }
         }
+      else if (foundNo && !foundError)
+        {
+         // -Wno<name>
+         this->DiagLevels[name] = DIAG_IGNORE;
+        }
+      else if (!foundNo && foundError)
+        {
+        // -Werror=<name>
+        this->DiagLevels[name] = DIAG_ERROR;
+        }
       else
       else
         {
         {
-        // -Wno<name>
-        this->DiagLevels[name] = DIAG_IGNORE;
+        // -Wno-error=<name>
+        this->DiagLevels[name] = std::min(this->DiagLevels[name],
+                                          DIAG_WARN);
         }
         }
       }
       }
     else if(arg.find("-U",0) == 0)
     else if(arg.find("-U",0) == 0)
@@ -1270,10 +1288,17 @@ int cmake::Configure()
     if (diagLevel == DIAG_IGNORE)
     if (diagLevel == DIAG_IGNORE)
       {
       {
       this->SetSuppressDeprecatedWarnings(true);
       this->SetSuppressDeprecatedWarnings(true);
+      this->SetDeprecatedWarningsAsErrors(false);
       }
       }
     else if (diagLevel == DIAG_WARN)
     else if (diagLevel == DIAG_WARN)
       {
       {
       this->SetSuppressDeprecatedWarnings(false);
       this->SetSuppressDeprecatedWarnings(false);
+      this->SetDeprecatedWarningsAsErrors(false);
+      }
+    else if (diagLevel == DIAG_ERROR)
+      {
+      this->SetSuppressDeprecatedWarnings(false);
+      this->SetDeprecatedWarningsAsErrors(true);
       }
       }
     }
     }
 
 
@@ -1283,9 +1308,11 @@ int cmake::Configure()
 
 
     const char* cachedWarnDeprecated =
     const char* cachedWarnDeprecated =
            this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
            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
     // don't overwrite deprecated warning setting from a previous invocation
-    if (!cachedWarnDeprecated)
+    if (!cachedWarnDeprecated && !cachedErrorDeprecated)
       {
       {
       setDeprecatedVariables = true;
       setDeprecatedVariables = true;
       }
       }
@@ -1294,19 +1321,34 @@ int cmake::Configure()
     if (diagLevel == DIAG_IGNORE)
     if (diagLevel == DIAG_IGNORE)
       {
       {
       this->SetSuppressDevWarnings(true);
       this->SetSuppressDevWarnings(true);
+      this->SetDevWarningsAsErrors(false);
 
 
       if (setDeprecatedVariables)
       if (setDeprecatedVariables)
         {
         {
         this->SetSuppressDeprecatedWarnings(true);
         this->SetSuppressDeprecatedWarnings(true);
+        this->SetDeprecatedWarningsAsErrors(false);
         }
         }
       }
       }
     else if (diagLevel == DIAG_WARN)
     else if (diagLevel == DIAG_WARN)
       {
       {
       this->SetSuppressDevWarnings(false);
       this->SetSuppressDevWarnings(false);
+      this->SetDevWarningsAsErrors(false);
+
+      if (setDeprecatedVariables)
+        {
+        this->SetSuppressDeprecatedWarnings(false);
+        this->SetDeprecatedWarningsAsErrors(false);
+        }
+      }
+    else if (diagLevel == DIAG_ERROR)
+      {
+      this->SetSuppressDevWarnings(false);
+      this->SetDevWarningsAsErrors(true);
 
 
       if (setDeprecatedVariables)
       if (setDeprecatedVariables)
         {
         {
         this->SetSuppressDeprecatedWarnings(false);
         this->SetSuppressDeprecatedWarnings(false);
+        this->SetDeprecatedWarningsAsErrors(true);
         }
         }
       }
       }
     }
     }
@@ -2547,16 +2589,45 @@ static bool cmakeCheckStampList(const char* stampList)
   return true;
   return true;
 }
 }
 
 
+cmake::MessageType cmake::ConvertMessageType(cmake::MessageType t)
+{
+  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)
 bool cmake::IsMessageTypeVisible(cmake::MessageType t)
 {
 {
   bool isVisible = true;
   bool isVisible = true;
 
 
   if(t == cmake::DEPRECATION_ERROR)
   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))
+    if(!this->GetDeprecatedWarningsAsErrors())
       {
       {
       isVisible = false;
       isVisible = false;
       }
       }
@@ -2568,6 +2639,13 @@ bool cmake::IsMessageTypeVisible(cmake::MessageType t)
       isVisible = false;
       isVisible = false;
       }
       }
     }
     }
+  else if (t == cmake::AUTHOR_ERROR)
+    {
+    if (!this->GetDevWarningsAsErrors())
+      {
+      isVisible = false;
+      }
+    }
   else if (t == cmake::AUTHOR_WARNING)
   else if (t == cmake::AUTHOR_WARNING)
     {
     {
     if (this->GetSuppressDevWarnings())
     if (this->GetSuppressDevWarnings())
@@ -2606,6 +2684,10 @@ bool cmake::PrintMessagePreamble(cmake::MessageType t, std::ostream& msg)
     {
     {
     msg << "CMake Warning (dev)";
     msg << "CMake Warning (dev)";
     }
     }
+  else if (t == cmake::AUTHOR_ERROR)
+    {
+    msg << "CMake Error (dev)";
+    }
   else
   else
     {
     {
     msg << "CMake Warning";
     msg << "CMake Warning";
@@ -2630,6 +2712,12 @@ void displayMessage(cmake::MessageType t, std::ostringstream& msg)
     msg <<
     msg <<
       "This warning is for project developers.  Use -Wno-dev to suppress it.";
       "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.
   // Add a terminating blank line.
   msg << "\n";
   msg << "\n";
@@ -2653,7 +2741,8 @@ void displayMessage(cmake::MessageType t, std::ostringstream& msg)
   // Output the message.
   // Output the message.
   if(t == cmake::FATAL_ERROR
   if(t == cmake::FATAL_ERROR
      || t == cmake::INTERNAL_ERROR
      || t == cmake::INTERNAL_ERROR
-     || t == cmake::DEPRECATION_ERROR)
+     || t == cmake::DEPRECATION_ERROR
+     || t == cmake::AUTHOR_ERROR)
     {
     {
     cmSystemTools::SetErrorOccured();
     cmSystemTools::SetErrorOccured();
     cmSystemTools::Message(msg.str().c_str(), "Error");
     cmSystemTools::Message(msg.str().c_str(), "Error");
@@ -2671,6 +2760,17 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
 {
 {
   cmListFileBacktrace backtrace = bt;
   cmListFileBacktrace backtrace = bt;
 
 
+  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))
   if (!force && !this->IsMessageTypeVisible(t))
     {
     {
     return;
     return;
@@ -2698,6 +2798,17 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
                          cmListFileContext const& lfc,
                          cmListFileContext const& lfc,
                          bool force)
                          bool force)
 {
 {
+  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))
   if (!force && !this->IsMessageTypeVisible(t))
     {
     {
     return;
     return;
@@ -2941,3 +3052,74 @@ void cmake::SetSuppressDeprecatedWarnings(bool b)
                       "functionality.",
                       "functionality.",
                       cmState::INTERNAL);
                       cmState::INTERNAL);
 }
 }
+
+bool cmake::GetDevWarningsAsErrors(cmMakefile const* mf)
+{
+  if (mf)
+    {
+    return (mf->IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") &&
+            !mf->IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS"));
+    }
+  else
+    {
+    const char* cacheEntryValue = this->State->GetCacheEntryValue(
+      "CMAKE_SUPPRESS_DEVELOPER_ERRORS");
+    return cacheEntryValue && cmSystemTools::IsOff(cacheEntryValue);
+    }
+}
+
+void cmake::SetDevWarningsAsErrors(bool b)
+{
+  std::string value;
+
+  // equivalent to -Werror=dev
+  if (b)
+    {
+    value = "FALSE";
+    }
+  // equivalent to -Wno-error=dev
+  else
+    {
+    value = "TRUE";
+    }
+
+  this->AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_ERRORS", value.c_str(),
+                      "Suppress errors that are meant for"
+                      " the author of the CMakeLists.txt files.",
+                      cmState::INTERNAL);
+}
+
+bool cmake::GetDeprecatedWarningsAsErrors(cmMakefile const* mf)
+{
+  if (mf)
+    {
+    return mf->IsOn("CMAKE_ERROR_DEPRECATED");
+    }
+  else
+    {
+    const char* cacheEntryValue = this->State->GetCacheEntryValue(
+      "CMAKE_ERROR_DEPRECATED");
+    return cmSystemTools::IsOn(cacheEntryValue);
+    }
+}
+
+void cmake::SetDeprecatedWarningsAsErrors(bool b)
+{
+  std::string value;
+
+  // equivalent to -Werror=deprecated
+  if (b)
+    {
+    value = "TRUE";
+    }
+  // equivalent to -Wno-error=deprecated
+  else
+    {
+    value = "FALSE";
+    }
+
+  this->AddCacheEntry("CMAKE_ERROR_DEPRECATED", value.c_str(),
+                      "Whether to issue deprecation errors for macros"
+                      " and functions.",
+                      cmState::INTERNAL);
+}

+ 39 - 3
Source/cmake.h

@@ -59,6 +59,7 @@ class cmake
  public:
  public:
   enum MessageType
   enum MessageType
   { AUTHOR_WARNING,
   { AUTHOR_WARNING,
+    AUTHOR_ERROR,
     FATAL_ERROR,
     FATAL_ERROR,
     INTERNAL_ERROR,
     INTERNAL_ERROR,
     MESSAGE,
     MESSAGE,
@@ -71,7 +72,8 @@ class cmake
   enum DiagLevel
   enum DiagLevel
   {
   {
     DIAG_IGNORE,
     DIAG_IGNORE,
-    DIAG_WARN
+    DIAG_WARN,
+    DIAG_ERROR
   };
   };
 
 
   /** \brief Describes the working modes of cmake */
   /** \brief Describes the working modes of cmake */
@@ -330,6 +332,28 @@ class cmake
    */
    */
   void SetSuppressDeprecatedWarnings(bool v);
   void SetSuppressDeprecatedWarnings(bool v);
 
 
+  /*
+   * Get the state of treating developer (author) warnings as errors.
+   * Returns false, by default, if warnings should not be treated as errors,
+   * true otherwise.
+   */
+  bool GetDevWarningsAsErrors(cmMakefile const* mf = NULL);
+  /**
+   * Set the state of treating developer (author) warnings as errors.
+   */
+  void SetDevWarningsAsErrors(bool v);
+
+  /*
+   * Get the state of treating deprecated warnings as errors.
+   * Returns false, by default, if warnings should not be treated as errors,
+   * true otherwise.
+   */
+  bool GetDeprecatedWarningsAsErrors(cmMakefile const* mf = NULL);
+  /**
+   * Set the state of treating developer (author) warnings as errors.
+   */
+  void SetDeprecatedWarningsAsErrors(bool v);
+
   /** Display a message to the user.  */
   /** Display a message to the user.  */
   void IssueMessage(cmake::MessageType t, std::string const& text,
   void IssueMessage(cmake::MessageType t, std::string const& text,
         cmListFileBacktrace const& backtrace = cmListFileBacktrace(),
         cmListFileBacktrace const& backtrace = cmListFileBacktrace(),
@@ -441,6 +465,12 @@ private:
   // Print a list of valid generators to stderr.
   // Print a list of valid generators to stderr.
   void PrintGeneratorList();
   void PrintGeneratorList();
 
 
+  /**
+   * Convert a message type between a warning and an error, based on the state
+   * of the error output CMake variables, in the cache.
+   */
+  cmake::MessageType ConvertMessageType(cmake::MessageType t);
+
   /*
   /*
    * Check if messages of this type should be output, based on the state of the
    * Check if messages of this type should be output, based on the state of the
    * warning and error output CMake variables, in the cache.
    * warning and error output CMake variables, in the cache.
@@ -457,10 +487,16 @@ private:
   {"-G <generator-name>", "Specify a build system generator."},\
   {"-G <generator-name>", "Specify a build system generator."},\
   {"-T <toolset-name>", "Specify toolset name if supported by generator."}, \
   {"-T <toolset-name>", "Specify toolset name if supported by generator."}, \
   {"-A <platform-name>", "Specify platform 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."},\
+  {"-Wno-dev", "Suppress developer warnings."},\
+  {"-Werror=dev", "Make developer warnings errors."},\
+  {"-Wno-error=dev", "Make developer warnings not errors."},\
   {"-Wdeprecated", "Enable deprecation warnings."},\
   {"-Wdeprecated", "Enable deprecation warnings."},\
-  {"-Wno-deprecated", "Suppress deprecation warnings."}
+  {"-Wno-deprecated", "Suppress deprecation 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) \
 #define FOR_EACH_C_FEATURE(F) \
   F(c_function_prototypes) \
   F(c_function_prototypes) \

+ 22 - 0
Tests/RunCMake/CommandLine/RunCMakeTest.cmake

@@ -187,6 +187,14 @@ set(RunCMake_TEST_OPTIONS -Wdev)
 run_cmake(Wdev)
 run_cmake(Wdev)
 unset(RunCMake_TEST_OPTIONS)
 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
 # -Wdev should not override deprecated options if specified
 set(RunCMake_TEST_OPTIONS -Wdev -Wno-deprecated)
 set(RunCMake_TEST_OPTIONS -Wdev -Wno-deprecated)
 run_cmake(Wno-deprecated)
 run_cmake(Wno-deprecated)
@@ -200,6 +208,11 @@ set(RunCMake_TEST_OPTIONS -Wdev)
 run_cmake(Wdeprecated)
 run_cmake(Wdeprecated)
 unset(RunCMake_TEST_OPTIONS)
 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)
 set(RunCMake_TEST_OPTIONS -Wdeprecated)
 run_cmake(Wdeprecated)
 run_cmake(Wdeprecated)
 unset(RunCMake_TEST_OPTIONS)
 unset(RunCMake_TEST_OPTIONS)
@@ -208,6 +221,14 @@ set(RunCMake_TEST_OPTIONS -Wno-deprecated)
 run_cmake(Wno-deprecated)
 run_cmake(Wno-deprecated)
 unset(RunCMake_TEST_OPTIONS)
 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)
+
 # Dev warnings should be on by default
 # Dev warnings should be on by default
 run_cmake(Wdev)
 run_cmake(Wdev)
 
 
@@ -224,6 +245,7 @@ unset(RunCMake_TEST_OPTIONS)
 
 
 run_cmake_command(W_bad-arg1 ${CMAKE_COMMAND} -W)
 run_cmake_command(W_bad-arg1 ${CMAKE_COMMAND} -W)
 run_cmake_command(W_bad-arg2 ${CMAKE_COMMAND} -Wno-)
 run_cmake_command(W_bad-arg2 ${CMAKE_COMMAND} -Wno-)
+run_cmake_command(W_bad-arg3 ${CMAKE_COMMAND} -Werror=)
 
 
 set(RunCMake_TEST_OPTIONS --debug-output)
 set(RunCMake_TEST_OPTIONS --debug-output)
 run_cmake(debug-output)
 run_cmake(debug-output)

+ 0 - 0
Tests/RunCMake/message/errormessage-result.txt → Tests/RunCMake/CommandLine/W_bad-arg3-result.txt


+ 2 - 0
Tests/RunCMake/CommandLine/W_bad-arg3-stderr.txt

@@ -0,0 +1,2 @@
+CMake Error: No warning name provided.
+CMake Error: Problem processing arguments. Aborting.

+ 1 - 0
Tests/RunCMake/CommandLine/Werror_deprecated-result.txt

@@ -0,0 +1 @@
+1

+ 4 - 0
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\)

+ 1 - 0
Tests/RunCMake/CommandLine/Werror_deprecated.cmake

@@ -0,0 +1 @@
+message(DEPRECATION "Some deprecated warning")

+ 1 - 0
Tests/RunCMake/CommandLine/Werror_dev-result.txt

@@ -0,0 +1 @@
+1

+ 11 - 0
Tests/RunCMake/CommandLine/Werror_dev-stderr.txt

@@ -0,0 +1,11 @@
+^CMake Error \(dev\) at Werror_dev.cmake:4 \(include\):
+  include\(\) given empty file name \(ignored\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This error is for project developers. Use -Wno-error=dev to suppress it.
+
+CMake Error \(dev\) at Werror_dev.cmake:7 \(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.$

+ 7 - 0
Tests/RunCMake/CommandLine/Werror_dev.cmake

@@ -0,0 +1,7 @@
+# with -Werror=dev this will also cause an (upgraded) AUTHOR_ERROR message,
+# checks that messages issued outside of the message command, by other CMake
+# commands, also are affected by -Werror=dev
+include("")
+
+# message command sets fatal occurred flag, so run it last
+message(AUTHOR_WARNING "Some author warning")

+ 4 - 0
Tests/RunCMake/CommandLine/Wno-error_deprecated-stderr.txt

@@ -0,0 +1,4 @@
+^CMake Deprecation Warning at Wno-error_deprecated.cmake:2 \(message\):
+  Some deprecated warning
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 2 - 0
Tests/RunCMake/CommandLine/Wno-error_deprecated.cmake

@@ -0,0 +1,2 @@
+# This should still produce a warning when -Wno-error=deprecated is specified
+message(DEPRECATION "Some deprecated warning")

+ 11 - 0
Tests/RunCMake/CommandLine/Wno-error_dev-stderr.txt

@@ -0,0 +1,11 @@
+^CMake Warning \(dev\) at Wno-error_dev.cmake:2 \(message\):
+  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.
+
+CMake Warning \(dev\) at Wno-error_dev.cmake:6 \(include\):
+  include\(\) given empty file name \(ignored\).
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.$

+ 7 - 0
Tests/RunCMake/CommandLine/Wno-error_dev.cmake

@@ -0,0 +1,7 @@
+# This should still produce a warning when -Wno-error=dev is specified
+message(AUTHOR_WARNING "Some author warning")
+
+# with -Wno-error=dev this will also cause an AUTHOR_WARNING message, checks
+# that messages issued outside of the message command, by other CMake commands,
+# also are affected by -Wno-error=dev
+include("")

+ 5 - 1
Tests/RunCMake/message/RunCMakeTest.cmake

@@ -3,4 +3,8 @@ include(RunCMake)
 run_cmake(defaultmessage)
 run_cmake(defaultmessage)
 run_cmake(nomessage)
 run_cmake(nomessage)
 run_cmake(warnmessage)
 run_cmake(warnmessage)
-run_cmake(errormessage)
+# message command sets fatal occurred flag, so check each type of error
+
+# seperately
+run_cmake(errormessage_deprecated)
+run_cmake(errormessage_dev)

+ 0 - 4
Tests/RunCMake/message/errormessage-stderr.txt

@@ -1,4 +0,0 @@
-CMake Deprecation Error at errormessage.cmake:4 \(message\):
-  This is an error
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)

+ 0 - 4
Tests/RunCMake/message/errormessage.cmake

@@ -1,4 +0,0 @@
-
-set(CMAKE_ERROR_DEPRECATED ON)
-
-message(DEPRECATION "This is an error")

+ 1 - 0
Tests/RunCMake/message/errormessage_deprecated-result.txt

@@ -0,0 +1 @@
+1

+ 4 - 0
Tests/RunCMake/message/errormessage_deprecated-stderr.txt

@@ -0,0 +1,4 @@
+^CMake Deprecation Error at errormessage_deprecated.cmake:3 \(message\):
+  This is a deprecation error
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 3 - 0
Tests/RunCMake/message/errormessage_deprecated.cmake

@@ -0,0 +1,3 @@
+set(CMAKE_ERROR_DEPRECATED ON)
+
+message(DEPRECATION "This is a deprecation error")

+ 1 - 0
Tests/RunCMake/message/errormessage_dev-result.txt

@@ -0,0 +1 @@
+1

+ 5 - 0
Tests/RunCMake/message/errormessage_dev-stderr.txt

@@ -0,0 +1,5 @@
+^CMake Error \(dev\) at errormessage_dev.cmake:3 \(message\):
+  This is a author error
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This error is for project developers. Use -Wno-error=dev to suppress it.$

+ 3 - 0
Tests/RunCMake/message/errormessage_dev.cmake

@@ -0,0 +1,3 @@
+set(CMAKE_SUPPRESS_DEVELOPER_ERRORS OFF)
+
+message(AUTHOR_WARNING "This is a author error")