Przeglądaj źródła

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 lat temu
rodzic
commit
59dac28856
32 zmienionych plików z 532 dodań i 37 usunięć
  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
  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``
  Enable deprecated functionality warnings.
 
@@ -97,3 +109,15 @@
 
  Suppress warnings for usage of deprecated functionality, 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.

+ 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
   :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);
 }
 
+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)
 {
   this->WarnUninitializedMode = value;

+ 8 - 0
Source/QtDialog/QCMake.h

@@ -99,6 +99,14 @@ public slots:
   bool getSuppressDeprecatedWarnings();
   /// set whether to do suppress deprecated warnings
   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
   void setWarnUninitializedMode(bool value);
   /// 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->suppressDeprecatedWarnings->setChecked(
     this->cmakeInstance->getSuppressDeprecatedWarnings());
+
+  this->developerWarningsAsErrors->setChecked(
+    this->cmakeInstance->getDevWarningsAsErrors());
+  this->deprecatedWarningsAsErrors->setChecked(
+    this->cmakeInstance->getDeprecatedWarningsAsErrors());
 }
 
 void WarningMessagesDialog::setupSignals()
 {
   QObject::connect(this->buttonBox, SIGNAL(accepted()),
                    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()
@@ -40,4 +55,45 @@ void WarningMessagesDialog::doAccept()
     this->suppressDeveloperWarnings->isChecked());
   this->cmakeInstance->setSuppressDeprecatedWarnings(
     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();
 
+  /**
+   * 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:
   QCMake* cmakeInstance;
 

+ 55 - 2
Source/QtDialog/WarningMessagesDialog.ui

@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>250</width>
-    <height>150</height>
+    <width>300</width>
+    <height>300</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -37,6 +37,9 @@
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
+        <property name="toolTip">
+         <string>Suppress developer (author) warnings.</string>
+        </property>
         <property name="text">
          <string>Developer Warnings</string>
         </property>
@@ -53,6 +56,9 @@
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
+        <property name="toolTip">
+         <string>Suppress deprecated warnings.</string>
+        </property>
         <property name="text">
          <string>Deprecated Warnings</string>
         </property>
@@ -64,6 +70,53 @@
      </layout>
     </widget>
    </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>
     <widget class="QDialogButtonBox" name="buttonBox">
      <property name="sizePolicy">

+ 15 - 14
Source/cmMessageCommand.cxx

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

+ 191 - 9
Source/cmake.cxx

@@ -291,6 +291,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
 
       std::string name;
       bool foundNo = false;
+      bool foundError = false;
       unsigned int nameStartPosition = 0;
 
       if (entry.find("no-", nameStartPosition) == 0)
@@ -299,6 +300,12 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
         nameStartPosition += 3;
         }
 
+      if (entry.find("error=", nameStartPosition) == 0)
+        {
+        foundError = true;
+        nameStartPosition += 6;
+        }
+
       name = entry.substr(nameStartPosition);
       if (name.empty())
         {
@@ -306,16 +313,27 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
         return false;
         }
 
-      if (!foundNo)
+      if (!foundNo && !foundError)
         {
         // -W<name>
         this->DiagLevels[name] = std::max(this->DiagLevels[name],
                                           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
         {
-        // -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)
@@ -1270,10 +1288,17 @@ int cmake::Configure()
     if (diagLevel == DIAG_IGNORE)
       {
       this->SetSuppressDeprecatedWarnings(true);
+      this->SetDeprecatedWarningsAsErrors(false);
       }
     else if (diagLevel == DIAG_WARN)
       {
       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 =
            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)
+    if (!cachedWarnDeprecated && !cachedErrorDeprecated)
       {
       setDeprecatedVariables = true;
       }
@@ -1294,19 +1321,34 @@ int cmake::Configure()
     if (diagLevel == DIAG_IGNORE)
       {
       this->SetSuppressDevWarnings(true);
+      this->SetDevWarningsAsErrors(false);
 
       if (setDeprecatedVariables)
         {
         this->SetSuppressDeprecatedWarnings(true);
+        this->SetDeprecatedWarningsAsErrors(false);
         }
       }
     else if (diagLevel == DIAG_WARN)
       {
       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)
         {
         this->SetSuppressDeprecatedWarnings(false);
+        this->SetDeprecatedWarningsAsErrors(true);
         }
       }
     }
@@ -2547,16 +2589,45 @@ static bool cmakeCheckStampList(const char* stampList)
   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 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))
+    if(!this->GetDeprecatedWarningsAsErrors())
       {
       isVisible = false;
       }
@@ -2568,6 +2639,13 @@ bool cmake::IsMessageTypeVisible(cmake::MessageType t)
       isVisible = false;
       }
     }
+  else if (t == cmake::AUTHOR_ERROR)
+    {
+    if (!this->GetDevWarningsAsErrors())
+      {
+      isVisible = false;
+      }
+    }
   else if (t == cmake::AUTHOR_WARNING)
     {
     if (this->GetSuppressDevWarnings())
@@ -2606,6 +2684,10 @@ bool cmake::PrintMessagePreamble(cmake::MessageType t, std::ostream& msg)
     {
     msg << "CMake Warning (dev)";
     }
+  else if (t == cmake::AUTHOR_ERROR)
+    {
+    msg << "CMake Error (dev)";
+    }
   else
     {
     msg << "CMake Warning";
@@ -2630,6 +2712,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";
@@ -2653,7 +2741,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");
@@ -2671,6 +2760,17 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
 {
   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))
     {
     return;
@@ -2698,6 +2798,17 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
                          cmListFileContext const& lfc,
                          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))
     {
     return;
@@ -2941,3 +3052,74 @@ void cmake::SetSuppressDeprecatedWarnings(bool b)
                       "functionality.",
                       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:
   enum MessageType
   { AUTHOR_WARNING,
+    AUTHOR_ERROR,
     FATAL_ERROR,
     INTERNAL_ERROR,
     MESSAGE,
@@ -71,7 +72,8 @@ class cmake
   enum DiagLevel
   {
     DIAG_IGNORE,
-    DIAG_WARN
+    DIAG_WARN,
+    DIAG_ERROR
   };
 
   /** \brief Describes the working modes of cmake */
@@ -330,6 +332,28 @@ class cmake
    */
   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.  */
   void IssueMessage(cmake::MessageType t, std::string const& text,
         cmListFileBacktrace const& backtrace = cmListFileBacktrace(),
@@ -441,6 +465,12 @@ private:
   // Print a list of valid generators to stderr.
   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
    * warning and error output CMake variables, in the cache.
@@ -457,10 +487,16 @@ private:
   {"-G <generator-name>", "Specify a build system generator."},\
   {"-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."},\
+  {"-Wno-dev", "Suppress developer warnings."},\
+  {"-Werror=dev", "Make developer warnings errors."},\
+  {"-Wno-error=dev", "Make developer warnings not errors."},\
   {"-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) \
   F(c_function_prototypes) \

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

@@ -187,6 +187,14 @@ set(RunCMake_TEST_OPTIONS -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)
@@ -200,6 +208,11 @@ 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)
@@ -208,6 +221,14 @@ 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)
+
 # Dev warnings should be on by default
 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-arg2 ${CMAKE_COMMAND} -Wno-)
+run_cmake_command(W_bad-arg3 ${CMAKE_COMMAND} -Werror=)
 
 set(RunCMake_TEST_OPTIONS --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(nomessage)
 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")