Răsfoiți Sursa

Add properties to run the cpplint style checker with the compiler

Create a `<LANG>_CPPLINT` target property (initialized by a
`CMAKE_<LANG>_CPPLINT` variable) to specify a `cpplint` style checker
command line to be run along with the compiler.
Jamie Snape 9 ani în urmă
părinte
comite
0618ddf6b1
37 a modificat fișierele cu 183 adăugiri și 8 ștergeri
  1. 0 0
      Auxiliary/vim/syntax/cmake.vim
  2. 1 0
      Help/manual/cmake-properties.7.rst
  3. 1 0
      Help/manual/cmake-variables.7.rst
  4. 13 0
      Help/prop_tgt/LANG_CPPLINT.rst
  5. 8 0
      Help/release/dev/add-LANG_CPPLINT.rst
  6. 6 0
      Help/variable/CMAKE_LANG_CPPLINT.rst
  7. 9 1
      Source/cmMakefileTargetGenerator.cxx
  8. 9 1
      Source/cmNinjaTargetGenerator.cxx
  9. 2 0
      Source/cmTarget.cxx
  10. 37 5
      Source/cmcmd.cxx
  11. 2 0
      Tests/RunCMake/CMakeLists.txt
  12. 1 1
      Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-stderr.txt
  13. 1 0
      Tests/RunCMake/Cpplint/C-Build-stdout.txt
  14. 1 0
      Tests/RunCMake/Cpplint/C-error-Build-result.txt
  15. 1 0
      Tests/RunCMake/Cpplint/C-error-Build-stdout.txt
  16. 1 0
      Tests/RunCMake/Cpplint/C-error-launch-Build-result.txt
  17. 1 0
      Tests/RunCMake/Cpplint/C-error-launch-Build-stdout.txt
  18. 3 0
      Tests/RunCMake/Cpplint/C-error-launch.cmake
  19. 3 0
      Tests/RunCMake/Cpplint/C-error.cmake
  20. 1 0
      Tests/RunCMake/Cpplint/C-launch-Build-stdout.txt
  21. 3 0
      Tests/RunCMake/Cpplint/C-launch.cmake
  22. 3 0
      Tests/RunCMake/Cpplint/C.cmake
  23. 3 0
      Tests/RunCMake/Cpplint/CMakeLists.txt
  24. 1 0
      Tests/RunCMake/Cpplint/CXX-Build-stdout.txt
  25. 1 0
      Tests/RunCMake/Cpplint/CXX-error-Build-result.txt
  26. 1 0
      Tests/RunCMake/Cpplint/CXX-error-Build-stdout.txt
  27. 1 0
      Tests/RunCMake/Cpplint/CXX-error-launch-Build-result.txt
  28. 1 0
      Tests/RunCMake/Cpplint/CXX-error-launch-Build-stdout.txt
  29. 3 0
      Tests/RunCMake/Cpplint/CXX-error-launch.cmake
  30. 3 0
      Tests/RunCMake/Cpplint/CXX-error.cmake
  31. 1 0
      Tests/RunCMake/Cpplint/CXX-launch-Build-stdout.txt
  32. 3 0
      Tests/RunCMake/Cpplint/CXX-launch.cmake
  33. 3 0
      Tests/RunCMake/Cpplint/CXX.cmake
  34. 26 0
      Tests/RunCMake/Cpplint/RunCMakeTest.cmake
  35. 4 0
      Tests/RunCMake/Cpplint/main.c
  36. 4 0
      Tests/RunCMake/Cpplint/main.cxx
  37. 21 0
      Tests/RunCMake/pseudo_cpplint.c

Fișier diff suprimat deoarece este prea mare
+ 0 - 0
Auxiliary/vim/syntax/cmake.vim


+ 1 - 0
Help/manual/cmake-properties.7.rst

@@ -211,6 +211,7 @@ Properties on Targets
    /prop_tgt/LABELS
    /prop_tgt/LANG_CLANG_TIDY
    /prop_tgt/LANG_COMPILER_LAUNCHER
+   /prop_tgt/LANG_CPPLINT
    /prop_tgt/LANG_INCLUDE_WHAT_YOU_USE
    /prop_tgt/LANG_VISIBILITY_PRESET
    /prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -284,6 +284,7 @@ Variables that Control the Build
    /variable/CMAKE_IOS_INSTALL_COMBINED
    /variable/CMAKE_LANG_CLANG_TIDY
    /variable/CMAKE_LANG_COMPILER_LAUNCHER
+   /variable/CMAKE_LANG_CPPLINT
    /variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE
    /variable/CMAKE_LANG_VISIBILITY_PRESET
    /variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY

+ 13 - 0
Help/prop_tgt/LANG_CPPLINT.rst

@@ -0,0 +1,13 @@
+<LANG>_CPPLINT
+--------------
+
+This property is supported only when ``<LANG>`` is ``C`` or ``CXX``.
+
+Specify a :ref:`;-list <CMake Language Lists>` containing a command line
+for the ``cpplint`` style checker.  The :ref:`Makefile Generators` and the
+:generator:`Ninja` generator will run ``cpplint`` along with the compiler
+and report any problems.
+
+This property is initialized by the value of the
+:variable:`CMAKE_<LANG>_CPPLINT` variable if it is set when a target is
+created.

+ 8 - 0
Help/release/dev/add-LANG_CPPLINT.rst

@@ -0,0 +1,8 @@
+add-LANG_CPPLINT
+----------------
+
+* A :prop_tgt:`<LANG>_CPPLINT` target property and supporting
+  :variable:`CMAKE_<LANG>_CPPLINT` variable were introduced to tell
+  the :ref:`Makefile Generators` and the :generator:`Ninja` generator to
+  run the ``cpplint`` style checker along with the compiler for ``C`` and
+  ``CXX`` languages.

+ 6 - 0
Help/variable/CMAKE_LANG_CPPLINT.rst

@@ -0,0 +1,6 @@
+CMAKE_<LANG>_CPPLINT
+--------------------
+
+Default value for :prop_tgt:`<LANG>_CPPLINT` target property. This variable
+is used to initialize the property on each target as it is created.  This
+is done only when ``<LANG>`` is ``C`` or ``CXX``.

+ 9 - 1
Source/cmMakefileTargetGenerator.cxx

@@ -631,7 +631,9 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
       const char* iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
       std::string const tidy_prop = lang + "_CLANG_TIDY";
       const char* tidy = this->GeneratorTarget->GetProperty(tidy_prop);
-      if ((iwyu && *iwyu) || (tidy && *tidy)) {
+      std::string const cpplint_prop = lang + "_CPPLINT";
+      const char* cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+      if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint)) {
         std::string run_iwyu = "$(CMAKE_COMMAND) -E __run_iwyu";
         if (iwyu && *iwyu) {
           run_iwyu += " --iwyu=";
@@ -640,6 +642,12 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
         if (tidy && *tidy) {
           run_iwyu += " --tidy=";
           run_iwyu += this->LocalGenerator->EscapeForShell(tidy);
+        }
+        if (cpplint && *cpplint) {
+          run_iwyu += " --cpplint=";
+          run_iwyu += this->LocalGenerator->EscapeForShell(cpplint);
+        }
+        if ((tidy && *tidy) || (cpplint && *cpplint)) {
           run_iwyu += " --source=";
           run_iwyu += sourceFile;
         }

+ 9 - 1
Source/cmNinjaTargetGenerator.cxx

@@ -600,7 +600,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
     const char* iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
     std::string const tidy_prop = lang + "_CLANG_TIDY";
     const char* tidy = this->GeneratorTarget->GetProperty(tidy_prop);
-    if ((iwyu && *iwyu) || (tidy && *tidy)) {
+    std::string const cpplint_prop = lang + "_CPPLINT";
+    const char* cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+    if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint)) {
       std::string run_iwyu = this->GetLocalGenerator()->ConvertToOutputFormat(
         cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
       run_iwyu += " -E __run_iwyu";
@@ -611,6 +613,12 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
       if (tidy && *tidy) {
         run_iwyu += " --tidy=";
         run_iwyu += this->GetLocalGenerator()->EscapeForShell(tidy);
+      }
+      if (cpplint && *cpplint) {
+        run_iwyu += " --cpplint=";
+        run_iwyu += this->GetLocalGenerator()->EscapeForShell(cpplint);
+      }
+      if ((tidy && *tidy) || (cpplint && *cpplint)) {
         run_iwyu += " --source=$in";
       }
       run_iwyu += " -- ";

+ 2 - 0
Source/cmTarget.cxx

@@ -255,6 +255,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
     this->SetPropertyDefault("MACOSX_RPATH", CM_NULLPTR);
     this->SetPropertyDefault("C_CLANG_TIDY", CM_NULLPTR);
     this->SetPropertyDefault("C_COMPILER_LAUNCHER", CM_NULLPTR);
+    this->SetPropertyDefault("C_CPPLINT", CM_NULLPTR);
     this->SetPropertyDefault("C_INCLUDE_WHAT_YOU_USE", CM_NULLPTR);
     this->SetPropertyDefault("LINK_WHAT_YOU_USE", CM_NULLPTR);
     this->SetPropertyDefault("C_STANDARD", CM_NULLPTR);
@@ -262,6 +263,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
     this->SetPropertyDefault("C_EXTENSIONS", CM_NULLPTR);
     this->SetPropertyDefault("CXX_CLANG_TIDY", CM_NULLPTR);
     this->SetPropertyDefault("CXX_COMPILER_LAUNCHER", CM_NULLPTR);
+    this->SetPropertyDefault("CXX_CPPLINT", CM_NULLPTR);
     this->SetPropertyDefault("CXX_INCLUDE_WHAT_YOU_USE", CM_NULLPTR);
     this->SetPropertyDefault("CXX_STANDARD", CM_NULLPTR);
     this->SetPropertyDefault("CXX_STANDARD_REQUIRED", CM_NULLPTR);

+ 37 - 5
Source/cmcmd.cxx

@@ -276,7 +276,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
     if (args[1] == "__run_iwyu") {
       if (args.size() < 3) {
         std::cerr << "__run_iwyu Usage: -E __run_iwyu [--iwyu=/path/iwyu]"
-                     " [--tidy=/path/tidy] -- compile command\n";
+                     " [--cpplint=/path/cpplint] [--tidy=/path/tidy]"
+                     " -- compile command\n";
         return 1;
       }
       bool doing_options = true;
@@ -285,6 +286,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
       std::string tidy;
       std::string sourceFile;
       std::string lwyu;
+      std::string cpplint;
       for (std::string::size_type cc = 2; cc < args.size(); cc++) {
         std::string const& arg = args[cc];
         if (arg == "--") {
@@ -297,6 +299,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
           sourceFile = arg.substr(9);
         } else if (doing_options && cmHasLiteralPrefix(arg, "--lwyu=")) {
           lwyu = arg.substr(7);
+        } else if (doing_options && cmHasLiteralPrefix(arg, "--cpplint=")) {
+          cpplint = arg.substr(10);
         } else if (doing_options) {
           std::cerr << "__run_iwyu given unknown argument: " << arg << "\n";
           return 1;
@@ -304,12 +308,14 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
           orig_cmd.push_back(arg);
         }
       }
-      if (tidy.empty() && iwyu.empty() && lwyu.empty()) {
-        std::cerr << "__run_iwyu missing --tidy= or --iwyu=\n";
+      if (tidy.empty() && iwyu.empty() && lwyu.empty() && cpplint.empty()) {
+        std::cerr << "__run_iwyu missing --cpplint=, --iwyu=, --lwyu=, and/or"
+                     " --tidy=\n";
         return 1;
       }
-      if (!tidy.empty() && sourceFile.empty()) {
-        std::cerr << "__run_iwyu --tidy= requires --source=\n";
+      if ((!cpplint.empty() || !tidy.empty()) && sourceFile.empty()) {
+        std::cerr << "__run_iwyu --cpplint= and/or __run_iwyu --tidy="
+                     " require --source=\n";
         return 1;
       }
       if (orig_cmd.empty() && lwyu.empty()) {
@@ -403,6 +409,32 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args)
           std::cerr << "Warning: " << stdOut;
         }
       }
+
+      if (!cpplint.empty()) {
+        // Construct the cpplint command line.
+        std::vector<std::string> cpplint_cmd;
+        cmSystemTools::ExpandListArgument(cpplint, cpplint_cmd, true);
+        cpplint_cmd.push_back(sourceFile);
+
+        // Run the cpplint command line.  Capture its output.
+        std::string stdOut;
+        if (!cmSystemTools::RunSingleCommand(cpplint_cmd, &stdOut, &stdOut,
+                                             &ret, CM_NULLPTR,
+                                             cmSystemTools::OUTPUT_NONE)) {
+          std::cerr << "Error running '" << cpplint_cmd[0] << "': " << stdOut
+                    << "\n";
+          return 1;
+        }
+
+        // Output the output from cpplint to stderr
+        std::cerr << stdOut;
+
+        // If cpplint exited with an error do the same.
+        if (ret != 0) {
+          return ret;
+        }
+      }
+
       ret = 0;
       // Now run the real compiler command and return its result value.
       if (lwyu.empty() &&

+ 2 - 0
Tests/RunCMake/CMakeLists.txt

@@ -340,8 +340,10 @@ if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
   endif()
   add_executable(pseudo_tidy pseudo_tidy.c)
   add_executable(pseudo_iwyu pseudo_iwyu.c)
+  add_executable(pseudo_cpplint pseudo_cpplint.c)
   add_RunCMake_test(ClangTidy -DPSEUDO_TIDY=$<TARGET_FILE:pseudo_tidy>)
   add_RunCMake_test(IncludeWhatYouUse -DPSEUDO_IWYU=$<TARGET_FILE:pseudo_iwyu>)
+  add_RunCMake_test(Cpplint -DPSEUDO_CPPLINT=$<TARGET_FILE:pseudo_cpplint>)
   add_RunCMake_test(CompilerLauncher)
 endif()
 

+ 1 - 1
Tests/RunCMake/CommandLine/E___run_iwyu-no-iwyu-stderr.txt

@@ -1 +1 @@
-^__run_iwyu missing --tidy= or --iwyu=$
+^__run_iwyu missing --cpplint=, --iwyu=, --lwyu=, and/or --tidy=$

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

@@ -0,0 +1 @@
+Total errors found: 0

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

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

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

@@ -0,0 +1 @@
+Tests[/\]RunCMake[/\]Cpplint[/\]main\.c:0:  message  \[category/category\] \[0\]

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

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

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

@@ -0,0 +1 @@
+Tests[/\]RunCMake[/\]Cpplint[/\]main\.c:0:  message  \[category/category\] \[0\]

+ 3 - 0
Tests/RunCMake/Cpplint/C-error-launch.cmake

@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(C-error.cmake)

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

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

+ 1 - 0
Tests/RunCMake/Cpplint/C-launch-Build-stdout.txt

@@ -0,0 +1 @@
+Total errors found: 0

+ 3 - 0
Tests/RunCMake/Cpplint/C-launch.cmake

@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(C.cmake)

+ 3 - 0
Tests/RunCMake/Cpplint/C.cmake

@@ -0,0 +1,3 @@
+enable_language(C)
+set(CMAKE_C_CPPLINT "${PSEUDO_CPPLINT}" --verbose=0 --linelength=80)
+add_executable(main main.c)

+ 3 - 0
Tests/RunCMake/Cpplint/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.7)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 1 - 0
Tests/RunCMake/Cpplint/CXX-Build-stdout.txt

@@ -0,0 +1 @@
+Total errors found: 0

+ 1 - 0
Tests/RunCMake/Cpplint/CXX-error-Build-result.txt

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

+ 1 - 0
Tests/RunCMake/Cpplint/CXX-error-Build-stdout.txt

@@ -0,0 +1 @@
+Tests[/\]RunCMake[/\]Cpplint[/\]main\.cxx:0:  message  \[category\/category\] \[0\]

+ 1 - 0
Tests/RunCMake/Cpplint/CXX-error-launch-Build-result.txt

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

+ 1 - 0
Tests/RunCMake/Cpplint/CXX-error-launch-Build-stdout.txt

@@ -0,0 +1 @@
+Tests[/\]RunCMake[/\]Cpplint[/\]main\.cxx:0:  message  \[category\/category\] \[0\]

+ 3 - 0
Tests/RunCMake/Cpplint/CXX-error-launch.cmake

@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(CXX-error.cmake)

+ 3 - 0
Tests/RunCMake/Cpplint/CXX-error.cmake

@@ -0,0 +1,3 @@
+enable_language(CXX)
+set(CMAKE_CXX_CPPLINT "${PSEUDO_CPPLINT}" --error)
+add_executable(main main.cxx)

+ 1 - 0
Tests/RunCMake/Cpplint/CXX-launch-Build-stdout.txt

@@ -0,0 +1 @@
+Total errors found: 0

+ 3 - 0
Tests/RunCMake/Cpplint/CXX-launch.cmake

@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(CXX.cmake)

+ 3 - 0
Tests/RunCMake/Cpplint/CXX.cmake

@@ -0,0 +1,3 @@
+enable_language(CXX)
+set(CMAKE_CXX_CPPLINT "${PSEUDO_CPPLINT}" --verbose=0 --linelength=80)
+add_executable(main main.cxx)

+ 26 - 0
Tests/RunCMake/Cpplint/RunCMakeTest.cmake

@@ -0,0 +1,26 @@
+include(RunCMake)
+
+set(RunCMake_TEST_OPTIONS "-DPSEUDO_CPPLINT=${PSEUDO_CPPLINT}")
+
+function(run_cpplint lang)
+  # Use a single build tree for tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${lang}-build")
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  run_cmake(${lang})
+  set(RunCMake_TEST_OUTPUT_MERGE 1)
+  run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build .)
+endfunction()
+
+run_cpplint(C)
+run_cpplint(CXX)
+run_cpplint(C-error)
+run_cpplint(CXX-error)
+
+if(NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
+  run_cpplint(C-launch)
+  run_cpplint(CXX-launch)
+  run_cpplint(C-error-launch)
+  run_cpplint(CXX-error-launch)
+endif()

+ 4 - 0
Tests/RunCMake/Cpplint/main.c

@@ -0,0 +1,4 @@
+int main(void)
+{
+  return 0;
+}

+ 4 - 0
Tests/RunCMake/Cpplint/main.cxx

@@ -0,0 +1,4 @@
+int main()
+{
+  return 0;
+}

+ 21 - 0
Tests/RunCMake/pseudo_cpplint.c

@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <string.h>
+
+int main(int argc, char* argv[])
+{
+  int error = 0;
+  int i;
+  for (i = 1; i < argc; ++i) {
+    if (strcmp(argv[i], "--error") == 0) {
+      error = 1;
+    }
+    if (argv[i][0] != '-') {
+      if (error) {
+        fprintf(stderr, "%s:0:  message  [category/category] [0]\n", argv[i]);
+      }
+      fprintf(stdout, "Done processing %s\nTotal errors found: %i\n", argv[i],
+              error);
+    }
+  }
+  return error;
+}

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff