Explorar o código

Add generator expression support to static code analysis hooks

Teach target properties `<LANG>_CPPCHECK`, `<LANG>_CPPLINT`,
`<LANG>_CLANG_TIDY` and `<LANG>_INCLUDE_WHAT_YOU_USE` to accept
generator expressions.
Stefan Schober %!s(int64=2) %!d(string=hai) anos
pai
achega
099934e313

+ 5 - 0
Help/prop_tgt/LANG_CLANG_TIDY.rst

@@ -25,3 +25,8 @@ command line.
 This property is initialized by the value of
 the :variable:`CMAKE_<LANG>_CLANG_TIDY` variable if it is set
 when a target is created.
+
+.. versionadded:: 3.27
+
+  This property supports
+  :manual:`generator expressions <cmake-generator-expressions(7)>`.

+ 5 - 0
Help/prop_tgt/LANG_CPPCHECK.rst

@@ -15,3 +15,8 @@ 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
 created.
+
+.. versionadded:: 3.27
+
+  This property supports
+  :manual:`generator expressions <cmake-generator-expressions(7)>`.

+ 5 - 0
Help/prop_tgt/LANG_CPPLINT.rst

@@ -13,3 +13,8 @@ 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.
+
+.. versionadded:: 3.27
+
+  This property supports
+  :manual:`generator expressions <cmake-generator-expressions(7)>`.

+ 5 - 0
Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst

@@ -13,3 +13,8 @@ compiler and report a warning if the tool reports any problems.
 This property is initialized by the value of
 the :variable:`CMAKE_<LANG>_INCLUDE_WHAT_YOU_USE` variable if it is set
 when a target is created.
+
+.. versionadded:: 3.27
+
+  This property supports
+  :manual:`generator expressions <cmake-generator-expressions(7)>`.

+ 7 - 0
Help/release/dev/lint-genex.rst

@@ -0,0 +1,7 @@
+lint-genex
+----------
+
+* The :prop_tgt:`<LANG>_CLANG_TIDY`, :prop_tgt:`<LANG>_CPPCHECK`,
+  :prop_tgt:`<LANG>_CPPLINT`, and :prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE`,
+  target properties now support
+  :manual:`generator expressions <cmake-generator-expressions(7)>`.

+ 38 - 5
Source/cmMakefileTargetGenerator.cxx

@@ -1067,18 +1067,51 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
     // Maybe insert an include-what-you-use runner.
     if (!compileCommands.empty() &&
         (lang == "C" || lang == "CXX" || lang == "OBJC" || lang == "OBJCXX")) {
-      std::string const tidy_prop = lang + "_CLANG_TIDY";
-      cmValue tidy = this->GeneratorTarget->GetProperty(tidy_prop);
+      cmValue tidy = nullptr;
       cmValue iwyu = nullptr;
       cmValue cpplint = nullptr;
       cmValue cppcheck = nullptr;
+      std::string evaluatedTIDY;
+      std::string evaluatedIWYU;
+      std::string evaluatedCPPlint;
+      std::string evaluatedCPPcheck;
+
+      std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY");
+      tidy = this->GeneratorTarget->GetProperty(tidy_prop);
+      evaluatedTIDY = cmGeneratorExpression::Evaluate(
+        *tidy, this->LocalGenerator, config, this->GeneratorTarget, nullptr,
+        this->GeneratorTarget, lang);
+      if (!evaluatedTIDY.empty()) {
+        tidy = cmValue(&evaluatedTIDY);
+      }
+
       if (lang == "C" || lang == "CXX") {
-        std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
+        std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
         iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
-        std::string const cpplint_prop = lang + "_CPPLINT";
+        evaluatedIWYU = cmGeneratorExpression::Evaluate(
+          *iwyu, this->LocalGenerator, config, this->GeneratorTarget, nullptr,
+          this->GeneratorTarget, lang);
+        if (!evaluatedIWYU.empty()) {
+          iwyu = cmValue(&evaluatedIWYU);
+        }
+
+        std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
         cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
-        std::string const cppcheck_prop = lang + "_CPPCHECK";
+        evaluatedCPPlint = cmGeneratorExpression::Evaluate(
+          *cpplint, this->LocalGenerator, config, this->GeneratorTarget,
+          nullptr, this->GeneratorTarget, lang);
+        if (!evaluatedCPPlint.empty()) {
+          cpplint = cmValue(&evaluatedCPPlint);
+        }
+
+        std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
         cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+        evaluatedCPPcheck = cmGeneratorExpression::Evaluate(
+          *cppcheck, this->LocalGenerator, config, this->GeneratorTarget,
+          nullptr, this->GeneratorTarget, lang);
+        if (!evaluatedCPPcheck.empty()) {
+          cppcheck = cmValue(&evaluatedCPPcheck);
+        }
       }
       if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
           cmNonempty(cppcheck)) {

+ 35 - 2
Source/cmNinjaTargetGenerator.cxx

@@ -908,18 +908,51 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
   // Maybe insert an include-what-you-use runner.
   if (!compileCmds.empty() &&
       (lang == "C" || lang == "CXX" || lang == "OBJC" || lang == "OBJCXX")) {
-    std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY");
-    cmValue tidy = this->GeneratorTarget->GetProperty(tidy_prop);
+    cmValue tidy = nullptr;
     cmValue iwyu = nullptr;
     cmValue cpplint = nullptr;
     cmValue cppcheck = nullptr;
+    std::string evaluatedTIDY;
+    std::string evaluatedIWYU;
+    std::string evaluatedCPPlint;
+    std::string evaluatedCPPcheck;
+
+    std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY");
+    tidy = this->GeneratorTarget->GetProperty(tidy_prop);
+    evaluatedTIDY = cmGeneratorExpression::Evaluate(
+      *tidy, this->LocalGenerator, config, this->GeneratorTarget, nullptr,
+      this->GeneratorTarget, lang);
+    if (!evaluatedTIDY.empty()) {
+      tidy = cmValue(&evaluatedTIDY);
+    }
+
     if (lang == "C" || lang == "CXX") {
       std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
       iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+      evaluatedIWYU = cmGeneratorExpression::Evaluate(
+        *iwyu, this->LocalGenerator, config, this->GeneratorTarget, nullptr,
+        this->GeneratorTarget, lang);
+      if (!evaluatedIWYU.empty()) {
+        iwyu = cmValue(&evaluatedIWYU);
+      }
+
       std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
       cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+      evaluatedCPPlint = cmGeneratorExpression::Evaluate(
+        *cpplint, this->LocalGenerator, config, this->GeneratorTarget, nullptr,
+        this->GeneratorTarget, lang);
+      if (!evaluatedCPPlint.empty()) {
+        cpplint = cmValue(&evaluatedCPPlint);
+      }
+
       std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
       cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+      evaluatedCPPcheck = cmGeneratorExpression::Evaluate(
+        *cppcheck, this->LocalGenerator, config, this->GeneratorTarget,
+        nullptr, this->GeneratorTarget, lang);
+      if (!evaluatedCPPcheck.empty()) {
+        cppcheck = cmValue(&evaluatedCPPcheck);
+      }
     }
     if (cmNonempty(iwyu) || cmNonempty(tidy) || cmNonempty(cpplint) ||
         cmNonempty(cppcheck)) {

+ 1 - 1
Tests/RunCMake/ClangTidy/CXX.cmake

@@ -1,3 +1,3 @@
 enable_language(CXX)
-set(CMAKE_CXX_CLANG_TIDY "${PSEUDO_TIDY}" -some -args)
+set(CMAKE_CXX_CLANG_TIDY "$<1:${PSEUDO_TIDY}>" -some -args)
 add_executable(main main.cxx)

+ 1 - 1
Tests/RunCMake/Cppcheck/CXX.cmake

@@ -1,3 +1,3 @@
 enable_language(CXX)
-set(CMAKE_CXX_CPPCHECK "${PSEUDO_CPPCHECK}")
+set(CMAKE_CXX_CPPCHECK "$<1:${PSEUDO_CPPCHECK}>")
 add_executable(main main.cxx)

+ 1 - 1
Tests/RunCMake/Cpplint/CXX.cmake

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

+ 1 - 1
Tests/RunCMake/IncludeWhatYouUse/CXX.cmake

@@ -1,3 +1,3 @@
 enable_language(CXX)
-set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${PSEUDO_IWYU}" -some -args)
+set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "$<1:${PSEUDO_IWYU}>" -some -args)
 add_executable(main main.cxx)

+ 4 - 4
Tests/RunCMake/MultiLint/CXX.cmake

@@ -1,6 +1,6 @@
 enable_language(CXX)
-set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${PSEUDO_IWYU}" -some -args)
-set(CMAKE_CXX_CLANG_TIDY "${PSEUDO_TIDY}" -some -args)
-set(CMAKE_CXX_CPPLINT "${PSEUDO_CPPLINT}" --verbose=0 --linelength=80)
-set(CMAKE_CXX_CPPCHECK "${PSEUDO_CPPCHECK}")
+set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "$<1:${PSEUDO_IWYU}>" -some -args)
+set(CMAKE_CXX_CLANG_TIDY "$<1:${PSEUDO_TIDY}>" -some -args)
+set(CMAKE_CXX_CPPLINT "$<1:${PSEUDO_CPPLINT}>" --verbose=0 --linelength=80)
+set(CMAKE_CXX_CPPCHECK "$<1:${PSEUDO_CPPCHECK}>")
 add_executable(main main.cxx)