Răsfoiți Sursa

Fail the build if cppcheck returns a non-zero exit code

This allows the build failure to be tuned with cppcheck's
options --error-exitcode=<n> and --exitcode-suppressions=<file>.
Harald Brinkmann 7 ani în urmă
părinte
comite
3b80cd77fb

+ 3 - 1
Help/prop_tgt/LANG_CPPCHECK.rst

@@ -6,7 +6,9 @@ This property is supported only when ``<LANG>`` is ``C`` or ``CXX``.
 Specify a :ref:`;-list <CMake Language Lists>` containing a command line
 for the ``cppcheck`` static analysis tool.  The :ref:`Makefile Generators`
 and the :generator:`Ninja` generator will run ``cppcheck`` along with the
-compiler and report any problems.
+compiler and report any problems.  If the command-line specifies the
+exit code options to ``cppcheck`` then the build  will fail if the
+tool returns non-zero.
 
 This property is initialized by the value of the
 :variable:`CMAKE_<LANG>_CPPCHECK` variable if it is set when a target is

+ 6 - 0
Help/release/dev/cppcheck-exit-code.rst

@@ -0,0 +1,6 @@
+cppcheck-exit-code
+------------------
+
+* When using cppcheck via the :variable:`CMAKE_<LANG>_CPPCHECK` variable
+  or :prop_tgt:`<LANG>_CPPCHECK` property, the build will now fail if
+  ``cppcheck`` returns non-zero as configured by its command-line options.

+ 7 - 3
Source/cmcmd.cxx

@@ -323,11 +323,15 @@ static int HandleCppCheck(const std::string& runCmd,
       stdErr.find("(performance)") != std::string::npos ||
       stdErr.find("(portability)") != std::string::npos ||
       stdErr.find("(information)") != std::string::npos) {
-    std::cerr << "Warning: cppcheck reported diagnostics:\n";
+    if (ret == 0) {
+      std::cerr << "Warning: cppcheck reported diagnostics:\n";
+    } else {
+      std::cerr << "Error: cppcheck reported failure:\n";
+    }
   }
   std::cerr << stdErr;
-  // ignore errors so build continues
-  return 0;
+
+  return ret;
 }
 
 typedef int (*CoCompileHandler)(const std::string&, const std::string&,

+ 1 - 1
Tests/RunCMake/Cppcheck/C-bad-Build-result.txt

@@ -1 +1 @@
-0
+[^0]

+ 1 - 0
Tests/RunCMake/Cppcheck/C-error-Build-result.txt

@@ -0,0 +1 @@
+[^0]

+ 1 - 0
Tests/RunCMake/Cppcheck/C-error-Build-stdout.txt

@@ -0,0 +1 @@
+.*Error: cppcheck reported failure.*error.*warning.*style.*performance.*information.*

+ 3 - 0
Tests/RunCMake/Cppcheck/C-error.cmake

@@ -0,0 +1,3 @@
+enable_language(C)
+set(CMAKE_C_CPPCHECK "${PSEUDO_CPPCHECK}" -error)
+add_executable(main main.c)

+ 1 - 0
Tests/RunCMake/Cppcheck/RunCMakeTest.cmake

@@ -15,6 +15,7 @@ endfunction()
 
 run_cppcheck(C)
 run_cppcheck(CXX)
+run_cppcheck(C-error)
 run_cppcheck(C-bad)
 
 if(NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")

+ 11 - 8
Tests/RunCMake/pseudo_cppcheck.c

@@ -5,13 +5,16 @@
 int main(int argc, char* argv[])
 {
   int i;
+  int result = 0;
   for (i = 1; i < argc; ++i) {
-    if (strcmp(argv[i], "-bad") == 0)
-      if (strcmp(argv[i], "-bad") == 0) {
-        fprintf(stdout, "stdout from bad command line arg '-bad'\n");
-        fprintf(stderr, "stderr from bad command line arg '-bad'\n");
-        return 1;
-      }
+    if (strcmp(argv[i], "-bad") == 0) {
+      fprintf(stdout, "stdout from bad command line arg '-bad'\n");
+      fprintf(stderr, "stderr from bad command line arg '-bad'\n");
+      return 1;
+    } else if (strcmp(argv[i], "-error") == 0) {
+      // The real cppcheck allows to set the exitcode with --error-exitcode
+      result = 5;
+    }
   }
   fprintf(stderr,
           "[/foo/bar.c:2]: (error) Array 'abc[10]' accessed at index 12,"
@@ -31,6 +34,6 @@ int main(int argc, char* argv[])
   fprintf(stderr,
           "[/foo/bar.c:2]: (information) cannot find all the include "
           "files (use --check-config for details)\n");
-  // we allow this to return 1 as we ignore it
-  return 1;
+
+  return result;
 }