From 099934e3139263b9f5bcb420c81ae7a10fdfb61e Mon Sep 17 00:00:00 2001 From: Stefan Schober Date: Fri, 24 Mar 2023 16:06:33 +0100 Subject: Add generator expression support to static code analysis hooks Teach target properties `_CPPCHECK`, `_CPPLINT`, `_CLANG_TIDY` and `_INCLUDE_WHAT_YOU_USE` to accept generator expressions. --- Help/prop_tgt/LANG_CLANG_TIDY.rst | 5 ++++ Help/prop_tgt/LANG_CPPCHECK.rst | 5 ++++ Help/prop_tgt/LANG_CPPLINT.rst | 5 ++++ Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst | 5 ++++ Help/release/dev/lint-genex.rst | 7 +++++ Source/cmMakefileTargetGenerator.cxx | 43 +++++++++++++++++++++++++---- Source/cmNinjaTargetGenerator.cxx | 37 +++++++++++++++++++++++-- Tests/RunCMake/ClangTidy/CXX.cmake | 2 +- Tests/RunCMake/Cppcheck/CXX.cmake | 2 +- Tests/RunCMake/Cpplint/CXX.cmake | 2 +- Tests/RunCMake/IncludeWhatYouUse/CXX.cmake | 2 +- Tests/RunCMake/MultiLint/CXX.cmake | 8 +++--- 12 files changed, 108 insertions(+), 15 deletions(-) create mode 100644 Help/release/dev/lint-genex.rst diff --git a/Help/prop_tgt/LANG_CLANG_TIDY.rst b/Help/prop_tgt/LANG_CLANG_TIDY.rst index 31f1876..1e10933 100644 --- a/Help/prop_tgt/LANG_CLANG_TIDY.rst +++ b/Help/prop_tgt/LANG_CLANG_TIDY.rst @@ -25,3 +25,8 @@ command line. This property is initialized by the value of the :variable:`CMAKE__CLANG_TIDY` variable if it is set when a target is created. + +.. versionadded:: 3.27 + + This property supports + :manual:`generator expressions `. diff --git a/Help/prop_tgt/LANG_CPPCHECK.rst b/Help/prop_tgt/LANG_CPPCHECK.rst index 80acbc0..0b2dee6 100644 --- a/Help/prop_tgt/LANG_CPPCHECK.rst +++ b/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__CPPCHECK` variable if it is set when a target is created. + +.. versionadded:: 3.27 + + This property supports + :manual:`generator expressions `. diff --git a/Help/prop_tgt/LANG_CPPLINT.rst b/Help/prop_tgt/LANG_CPPLINT.rst index be6db46..38a1669 100644 --- a/Help/prop_tgt/LANG_CPPLINT.rst +++ b/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__CPPLINT` variable if it is set when a target is created. + +.. versionadded:: 3.27 + + This property supports + :manual:`generator expressions `. diff --git a/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst b/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst index eebef56..19b97f7 100644 --- a/Help/prop_tgt/LANG_INCLUDE_WHAT_YOU_USE.rst +++ b/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__INCLUDE_WHAT_YOU_USE` variable if it is set when a target is created. + +.. versionadded:: 3.27 + + This property supports + :manual:`generator expressions `. diff --git a/Help/release/dev/lint-genex.rst b/Help/release/dev/lint-genex.rst new file mode 100644 index 0000000..8da30b0 --- /dev/null +++ b/Help/release/dev/lint-genex.rst @@ -0,0 +1,7 @@ +lint-genex +---------- + +* The :prop_tgt:`_CLANG_TIDY`, :prop_tgt:`_CPPCHECK`, + :prop_tgt:`_CPPLINT`, and :prop_tgt:`_INCLUDE_WHAT_YOU_USE`, + target properties now support + :manual:`generator expressions `. diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index e6f8cdd..3112acd 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/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)) { diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 4c0f935..e163edb 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/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)) { diff --git a/Tests/RunCMake/ClangTidy/CXX.cmake b/Tests/RunCMake/ClangTidy/CXX.cmake index 2d22325..3214122 100644 --- a/Tests/RunCMake/ClangTidy/CXX.cmake +++ b/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) diff --git a/Tests/RunCMake/Cppcheck/CXX.cmake b/Tests/RunCMake/Cppcheck/CXX.cmake index 3b79471..7030c61 100644 --- a/Tests/RunCMake/Cppcheck/CXX.cmake +++ b/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) diff --git a/Tests/RunCMake/Cpplint/CXX.cmake b/Tests/RunCMake/Cpplint/CXX.cmake index 35f05ee..b58609c 100644 --- a/Tests/RunCMake/Cpplint/CXX.cmake +++ b/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) diff --git a/Tests/RunCMake/IncludeWhatYouUse/CXX.cmake b/Tests/RunCMake/IncludeWhatYouUse/CXX.cmake index 896930c..8780bb6 100644 --- a/Tests/RunCMake/IncludeWhatYouUse/CXX.cmake +++ b/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) diff --git a/Tests/RunCMake/MultiLint/CXX.cmake b/Tests/RunCMake/MultiLint/CXX.cmake index dc30146..3e99e73 100644 --- a/Tests/RunCMake/MultiLint/CXX.cmake +++ b/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) -- cgit v0.12